1use std::fmt::{Display, Formatter, Result as FormatResult};
2use proto::HyperResponse;
3use prelude::*;
4use self::header::Header;
5
6pub struct Error {
16 headers: Headers,
17 status: StatusCode,
18 description: &'static str,
19 cause: Option<Box<::std::error::Error>>,
20}
21impl Error {
22 pub fn new(status: StatusCode, description: &'static str) -> Error {
23 Error {
24 status: status,
25 headers: Headers::default(),
26 description: description,
27 cause: None,
28 }
29 }
30 pub fn status(&self) -> StatusCode {
31 self.status
32 }
33
34 pub fn internal(description: &'static str) -> Error {
35 Error::new(StatusCode::InternalServerError, description)
36 }
37 pub fn unauthorized(description: &'static str) -> Error {
38 Error::new(StatusCode::Unauthorized, description)
39 }
40 pub fn bad_request(description: &'static str) -> Error {
41 Error::new(StatusCode::BadRequest, description)
42 }
43 pub fn forbidden(description: &'static str) -> Error {
44 Error::new(StatusCode::Forbidden, description)
45 }
46 pub fn not_found(description: &'static str) -> Error {
47 Error::new(StatusCode::NotFound, description)
48 }
49 pub fn method_not_allowed() -> Error {
50 Error::new(StatusCode::NotFound, "Method is not allowed.")
51 }
52
53 pub fn set_header<H: Header>(&mut self, header: H) {
54 self.headers.set(header);
55 }
56 pub fn set_headers(&mut self, headers: Headers) {
57 self.headers = headers;
58 }
59 pub fn set_cause<E>(&mut self, err: E)
60 where E: 'static + ::std::error::Error {
61 self.cause = Some(Box::new(err));
62 }
63
64
65 pub fn with_header<H: Header>(mut self, header: H) -> Self {
66 self.headers.set(header);
67 self
68 }
69 pub fn with_headers(mut self, headers: Headers) -> Self {
70 self.headers = headers;
71 self
72 }
73 pub fn with_cause<E>(mut self, err: E) -> Self
74 where E: 'static + ::std::error::Error {
75 self.cause = Some(Box::new(err));
76 self
77 }
78}
79impl ::std::fmt::Debug for Error {
80 fn fmt(&self, f: &mut Formatter) -> FormatResult {
81 f.write_str(self.description)
82 }
83}
84impl Display for Error {
85 fn fmt(&self, f: &mut Formatter) -> FormatResult {
86 f.write_str(self.description)
87 }
88}
89impl ::std::error::Error for Error {
90 fn description(&self) -> &str {
91 self.description
92 }
93 fn cause(&self) -> Option<&::std::error::Error> {
94 match self.cause {
95 Some(ref e) => Some(&**e),
96 None => ::std::option::Option::None,
97 }
98 }
99}
100impl Into<HyperResponse> for Error {
101 fn into(self) -> HyperResponse {
102 use hyper::header::{ContentType, ContentLength};
103 let body = format!(r#"{{"msg":"{}"}}"#, self.description).into_bytes();
104 HyperResponse::new()
105 .with_status(self.status)
106 .with_headers(self.headers)
107 .with_header(ContentType("application/json; charset=UTF-8".parse().unwrap()))
108 .with_header(ContentLength(body.len() as u64))
109 .with_body(body)
110 }
111}
112
113pub type Result<T> = ::std::result::Result<T, Error>;