Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ActionDispatch::DebugExceptions interceptors #23868

Merged

Conversation

gsamokovarov
Copy link
Contributor

Plugins interacting with the exceptions caught and displayed by
ActionDispatch::DebugExceptions currently have to monkey patch it to get
the much needed exception for their calculation.

With DebugExceptions.register_interceptor, plugin authors can hook into
DebugExceptions and process the exception, before being rendered. They
can store it into the request and process it on the way back of the
middleware chain execution or act on it straight in the interceptor.

The interceptors can be plain blocks, procs, lambdas or any object that
responds to #call.

You can see web-console implemented through the interceptor API here.
Other plugin authors can benefit from this API as well. Most of the error
reporting plugins can use this.

@rails-bot
Copy link

r? @matthewd

(@rails-bot has picked a reviewer for you, use r? to override)

@gsamokovarov gsamokovarov force-pushed the debug-exceptions-interceptors branch 2 times, most recently from 97c9795 to bf198fe Compare February 24, 2016 22:14
backtrace_cleaner = request.get_header('action_dispatch.backtrace_cleaner')
wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)

@interceptors.each do |interceptor|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get rid of the transitory @interceptors, and just call self.class.interceptors here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Injected it, so I can test it more easily – no need to keep track of the global state during the test run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 I just think it would make sense to use the direct variable we will iterating on, instead of creating a shadow variable, that we won't even be changing.

@nateberkopec
Copy link
Contributor

As the maintainer of an exception notifier (sentry-raven) I am wholeheartedly for this PR.

raise exception unless request.show_exceptions?
render_exception(request, exception)
render_exception(request, exception, wrapper)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this breaks the render_exception interface, and plugin authors already depend on it. I'm going with the duplicated code approach. Yeah, I like DRY code, but sometimes the duplication is so much better than breaking interfaces or leaking abstractions.

@gsamokovarov gsamokovarov force-pushed the debug-exceptions-interceptors branch 2 times, most recently from b6d25e4 to 24423aa Compare February 27, 2016 16:12
@tgxworld
Copy link
Contributor

tgxworld commented Apr 13, 2018

@gsamokovarov Is web-console still monkey patching? At Discourse, we maintain logster which is monkey patching as well and being able to register callbacks in the middleware would be great for us.

@rafaelfranca @matthewd Is there anything I can do to help move this forward?

@gsamokovarov
Copy link
Contributor Author

gsamokovarov commented Apr 13, 2018

@tgxworld Yes, it is still monkey patching... You can make logster and web-console play together by requiring it after web-console, e.g. put logster after web-console it in the Gemfile.

I still stand by the interceptors, though. They are super simple and provide what most of the plugins monkey patching ActionDispatch::DebugExceptions need.

@rafaelfranca
Copy link
Member

The idea looks good to me. @gsamokovarov can you rebase it?

@gsamokovarov gsamokovarov force-pushed the debug-exceptions-interceptors branch 3 times, most recently from 95fd046 to 7c0d767 Compare April 20, 2018 10:38
Plugins interacting with the exceptions caught and displayed by
ActionDispatch::DebugExceptions currently have to monkey patch it to get
the much needed exception for their calculation.

With DebugExceptions.register_interceptor, plugin authors can hook into
DebugExceptions and process the exception, before being rendered. They
can store it into the request and process it on the way back of the
middleware chain execution or act on it straight in the interceptor.

The interceptors can be play blocks, procs, lambdas or any object that
responds to `#call`.
@gsamokovarov
Copy link
Contributor Author

@rafaelfranca I have rebased it. 👌

@rafaelfranca rafaelfranca merged commit 357559f into rails:master Apr 20, 2018
@gsamokovarov gsamokovarov deleted the debug-exceptions-interceptors branch April 21, 2018 15:21
@tgxworld
Copy link
Contributor

😍 Thank you @gsamokovarov and @rafaelfranca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants