forked from nickel-org/nickel.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnickel_error.rs
90 lines (82 loc) · 3.04 KB
/
nickel_error.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use std::borrow::Cow;
use hyper::status::StatusCode;
use std::io;
use std::error::Error;
use response::Response;
use hyper::net::{Fresh, Streaming};
/// NickelError is the basic error type for HTTP errors as well as user defined errors.
/// One can pattern match against the `kind` property to handle the different cases.
pub struct NickelError<'a, D: 'a = ()> {
pub stream: Option<Response<'a, D, Streaming>>,
pub message: Cow<'static, str>
}
impl<'a, D> NickelError<'a, D> {
/// Creates a new `NickelError` instance.
///
/// You should probably use `Response#error` in favor of this.
///
/// # Examples
/// ```{rust}
/// # extern crate nickel;
///
/// # fn main() {
/// use nickel::{Request, Response, MiddlewareResult, NickelError};
/// use nickel::status::StatusCode;
///
/// # #[allow(dead_code)]
/// fn handler<'a, D>(_: &mut Request<D>, res: Response<'a, D>) -> MiddlewareResult<'a, D> {
/// Err(NickelError::new(res, "Error Parsing JSON", StatusCode::BadRequest))
/// }
/// # }
/// ```
pub fn new<T>(mut stream: Response<'a, D, Fresh>,
message: T,
status_code: StatusCode) -> NickelError<'a, D>
where T: Into<Cow<'static, str>> {
stream.set(status_code);
match stream.start() {
Ok(stream) =>
NickelError {
stream: Some(stream),
message: message.into(),
},
Err(e) => e
}
}
/// Creates a new `NickelError` without a `Response`.
///
/// This should only be called in a state where the `Response` has
/// failed in an unrecoverable state. If there is an available
/// `Response` then it must be provided to `new` so that the
/// underlying stream can be flushed, allowing future requests.
///
/// This is considered `unsafe` as deadlock can occur if the `Response`
/// does not have the underlying stream flushed when processing is finished.
pub unsafe fn without_response<T>(message: T) -> NickelError<'a, D>
where T: Into<Cow<'static, str>> {
NickelError {
stream: None,
message: message.into(),
}
}
pub fn end(self) -> Option<io::Result<()>> {
self.stream.map(|s| s.end())
}
}
impl<'a, T, D> From<(Response<'a, D>, (StatusCode, T))> for NickelError<'a, D>
where T: Into<Box<Error + 'static>> {
fn from((res, (errorcode, err)): (Response<'a, D>, (StatusCode, T))) -> NickelError<'a, D> {
let err = err.into();
NickelError::new(res, err.description().to_string(), errorcode)
}
}
impl<'a, D> From<(Response<'a, D>, String)> for NickelError<'a, D> {
fn from((res, msg): (Response<'a, D>, String)) -> NickelError<'a, D> {
NickelError::new(res, msg, StatusCode::InternalServerError)
}
}
impl<'a, D> From<(Response<'a, D>, StatusCode)> for NickelError<'a, D> {
fn from((res, code): (Response<'a, D>, StatusCode)) -> NickelError<'a, D> {
NickelError::new(res, "", code)
}
}