Merge pull request #676 from Ryman/500_on_panic
fix(response): respond with a 500 if a handler panics
This commit is contained in:
@@ -7,6 +7,7 @@ use std::marker::PhantomData;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
use time::now_utc;
|
use time::now_utc;
|
||||||
|
|
||||||
@@ -237,6 +238,10 @@ enum Body {
|
|||||||
impl<'a, T: Any> Drop for Response<'a, T> {
|
impl<'a, T: Any> Drop for Response<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if TypeId::of::<T>() == TypeId::of::<Fresh>() {
|
if TypeId::of::<T>() == TypeId::of::<Fresh>() {
|
||||||
|
if thread::panicking() {
|
||||||
|
self.status = status::StatusCode::InternalServerError;
|
||||||
|
}
|
||||||
|
|
||||||
let mut body = match self.write_head() {
|
let mut body = match self.write_head() {
|
||||||
Ok(Body::Chunked) => ChunkedWriter(self.body.get_mut()),
|
Ok(Body::Chunked) => ChunkedWriter(self.body.get_mut()),
|
||||||
Ok(Body::Sized(len)) => SizedWriter(self.body.get_mut(), len),
|
Ok(Body::Sized(len)) => SizedWriter(self.body.get_mut(), len),
|
||||||
@@ -343,6 +348,43 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fresh_drop_panicing() {
|
||||||
|
use std::thread;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use status::StatusCode;
|
||||||
|
|
||||||
|
let stream = MockStream::new();
|
||||||
|
let stream = Arc::new(Mutex::new(stream));
|
||||||
|
let inner_stream = stream.clone();
|
||||||
|
let join_handle = thread::spawn(move || {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
let mut stream = inner_stream.lock().unwrap();
|
||||||
|
let mut res = Response::new(&mut *stream, &mut headers);
|
||||||
|
*res.status_mut() = StatusCode::NotFound;
|
||||||
|
|
||||||
|
panic!("inside")
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(join_handle.join().is_err());
|
||||||
|
|
||||||
|
let stream = match stream.lock() {
|
||||||
|
Err(poisoned) => poisoned.into_inner().clone(),
|
||||||
|
Ok(_) => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
lines! { stream =
|
||||||
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
|
_date,
|
||||||
|
_transfer_encoding,
|
||||||
|
"",
|
||||||
|
"0",
|
||||||
|
"" // empty zero body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_streaming_drop() {
|
fn test_streaming_drop() {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|||||||
Reference in New Issue
Block a user