Skip to content

Commit

Permalink
fix(response): respond with a 500 if a handler panics
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryman committed Oct 29, 2015
1 parent 9cbf549 commit 63c6762
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/server/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::marker::PhantomData;
use std::mem;
use std::io::{self, Write};
use std::ptr;
use std::thread;

use time::now_utc;

Expand Down Expand Up @@ -237,6 +238,10 @@ enum Body {
impl<'a, T: Any> Drop for Response<'a, T> {
fn drop(&mut self) {
if TypeId::of::<T>() == TypeId::of::<Fresh>() {
if thread::panicking() {
self.status = status::StatusCode::InternalServerError;
}

let mut body = match self.write_head() {
Ok(Body::Chunked) => ChunkedWriter(self.body.get_mut()),
Ok(Body::Sized(len)) => SizedWriter(self.body.get_mut(), len),
Expand Down Expand Up @@ -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]
fn test_streaming_drop() {
use std::io::Write;
Expand Down

0 comments on commit 63c6762

Please sign in to comment.