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

Catch synchronous panics in NewHandlerService #60

Merged
merged 7 commits into from
Oct 24, 2017
Merged

Conversation

smangelsdorf
Copy link
Contributor

This is part 1 of solving #17:

A catch_unwind which handles a panic in a Handler and/or Middleware below, before the Future is returned

A few notes about this:

  1. We've introduced RefUnwindSafe in quite a few places. The need for this originated from NewHandler: RefUnwindSafe, which has transitively required the trait bound elsewhere;
  2. The regex::Regex type (which we use for segment constraints) isn't unwind safe due to interior mutability. We work around this by:
    1. Reducing the surface area to only the is_match function, via our ConstrainedSegmentRegex wrapper; and
    2. Trapping a panic (which should be impossible) therein, and aborting the process to avoid leaving invalid state in the thread-local storage inside Regex.
  3. This PR adds a catch_unwind to the NewHandlerService logic, which is intended to be a last resort effort to stop the application server falling over. Future work will hopefully see a more graceful panic-catching middleware which gives the ResponseExtender time to intervene before the Response is sent. There's no ability, nor any intention, to be able to customise the response which is sent at the NewHandlerService level.

`NewHandlerService::call` is gaining more logic, so some of the existing
logic needs tidying up to keep things sane.
When something panics in a Gotham application, we can trap the panic at
the `NewHandlerService` level and respond with a blank 500 error
response. This is intended to be a last-ditch attempt at stopping the
application falling over, and panics should instead be handled in a
couple of more intelligent ways:

1. Applications should not cause a panic for anything but the most dire
   of runtime errors; and
2. A panic-catching middleware will be introduced which attempts to
   handle these panics more gracefully.

Notably, this logic **does not** prevent panics occurring if the
returned `Future` panics.

Ref #17
@coveralls
Copy link

coveralls commented Oct 20, 2017

Coverage Status

Coverage increased (+1.6%) to 78.433% when pulling 8d6e1f9 on catch-panics into 1fa507e on master.

@bradleybeddoes bradleybeddoes merged commit f1cc16f into master Oct 24, 2017
@smangelsdorf smangelsdorf deleted the catch-panics branch October 24, 2017 23:48
smangelsdorf added a commit that referenced this pull request Dec 5, 2017
After #60, the OrderedRegex was refactored into ConstrainedSegmentRegex
to be unwind-safe, and so the original `#[derive(Clone)]` no longer
works.
smangelsdorf added a commit that referenced this pull request Dec 5, 2017
The changes in #60 require unwind safety in the pipeline and handlers
used in the router builder API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants