Add on_trap callback hook for observability and custom handling - #6
Merged
Merged
Conversation
Copilot
AI
changed the title
[WIP] Add on_trap callback hook for observability and custom handling
Add on_trap callback hook for observability and custom handling
Jul 8, 2026
Owner
|
@copilot please update README. bump version to 0.3.2 and update the CHANGELOG. |
Contributor
Author
Done in commit
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a first-class on_trap callback hook to the Spamtrap controller integration so consuming apps can reliably observe and handle trap events (honeypot and nonce) without inferring behavior from the implicit head 200.
Changes:
- Introduces global
Spamtrap.on_trapconfiguration and a per-declarationon_trap:override option. - Invokes the callback on both honeypot and nonce trap paths with
reason:andrequest:keyword args, rescuing callback errors to preserve the silent discard behavior. - Adds tests, routes, and documentation (README + CHANGELOG) and bumps the gem version.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/test_helper.rb | Adds routes for the new on_trap test controllers. |
| test/controller_test.rb | Adds controller fixtures and test coverage for global/per-declaration callbacks and error resilience. |
| README.rdoc | Documents the on_trap API and usage patterns. |
| lib/spamtrap/version.rb | Bumps version to 0.3.2. |
| lib/spamtrap/controller.rb | Extracts on_trap: option and invokes the callback for honeypot/nonce traps via a helper method. |
| lib/spamtrap.rb | Adds global on_trap configuration accessor. |
| CHANGELOG.md | Adds a new 0.3.2 changelog entry describing the feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return unless callback.respond_to?(:call) | ||
| callback.call(reason: reason, request: request) | ||
| rescue StandardError => e | ||
| Rails.logger.error "Spamtrap on_trap callback raised: #{e.class}: #{e.message}" |
cedric
pushed a commit
that referenced
this pull request
Jul 8, 2026
* Initial plan * Add on_trap callback hook for observability and custom handling * Use thread-local variable instead of global in on_trap test * Bump version to 0.3.2, add CHANGELOG, update README with on_trap docs ---------
cedric
added a commit
that referenced
this pull request
Jul 8, 2026
* Initial plan * Add on_trap callback hook for observability and custom handling * Use thread-local variable instead of global in on_trap test * Bump version to 0.3.2, add CHANGELOG, update README with on_trap docs ---------
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No first-class way existed to hook into a trap event — consuming applications had to detect the implicit
head 200indirectly, which is fragile and ambiguous. This adds a configurableon_trapcallback invoked on every trap (honeypot or nonce), at both global and per-declaration scope.Changes
lib/spamtrap.rbattr_accessor :on_trapto module configlib/spamtrap/controller.rbon_trap:per-declaration option using the same:globalsentinel pattern asnonce:andmutate:spamtrap_invoke_on_trap(reason, on_trap_opt)beforehead 200in both honeypot and nonce trap pathsspamtrap_invoke_on_trap— resolves global vs per-declaration callback, invokes it withreason:(:honeypotor:nonce) andrequest:kwargs, and wraps inrescue StandardErrorso a broken callback never prevents the silent discardtest/nil, per-declaration precedence over global, and error resilienceAPI
Backwards compatible — no behaviour change when
on_trapis not set.