Skip to content

Commit 2003a99

Browse files
authored
Merge pull request #438 from http-rs/errors
Enable use of `?` in Endpoint
2 parents 952fa73 + 38a9891 commit 2003a99

26 files changed

+219
-204
lines changed

examples/chunked.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() -> Result<(), std::io::Error> {
1010
app.at("/").get(|_| async move {
1111
let file = fs::File::open(file!()).await.unwrap();
1212
let res = Response::new(StatusCode::Ok).body(BufReader::new(file));
13-
res
13+
Ok(res)
1414
});
1515
app.listen("127.0.0.1:8080").await?;
1616
Ok(())

examples/cookies.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ use tide::{Request, Response};
55

66
/// Tide will use the the `Cookies`'s `Extract` implementation to build this parameter.
77
///
8-
async fn retrieve_cookie(cx: Request<()>) -> String {
9-
format!("hello cookies: {:?}", cx.cookie("hello").unwrap())
8+
async fn retrieve_cookie(cx: Request<()>) -> tide::Result<String> {
9+
Ok(format!("hello cookies: {:?}", cx.cookie("hello").unwrap()))
1010
}
1111

12-
async fn set_cookie(_req: Request<()>) -> Response {
12+
async fn set_cookie(_req: Request<()>) -> tide::Result<Response> {
1313
let mut res = tide::Response::new(StatusCode::Ok);
1414
res.set_cookie(Cookie::new("hello", "world"));
15-
res
15+
Ok(res)
1616
}
1717

18-
async fn remove_cookie(_req: Request<()>) -> Response {
18+
async fn remove_cookie(_req: Request<()>) -> tide::Result<Response> {
1919
let mut res = tide::Response::new(StatusCode::Ok);
2020
res.remove_cookie(Cookie::named("hello"));
21-
res
21+
Ok(res)
2222
}
2323

2424
fn main() -> Result<(), std::io::Error> {

examples/fib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn fib(n: usize) -> usize {
99
}
1010
}
1111

12-
async fn fibsum(req: Request<()>) -> String {
12+
async fn fibsum(req: Request<()>) -> tide::Result<String> {
1313
use std::time::Instant;
1414
let n: usize = req.param("n").unwrap_or(0);
1515
// Start a stopwatch
@@ -19,10 +19,11 @@ async fn fibsum(req: Request<()>) -> String {
1919
// Stop the stopwatch
2020
let duration = Instant::now().duration_since(start).as_secs();
2121
// Return the answer
22-
format!(
22+
let res = format!(
2323
"The fib of {} is {}.\nIt was computed in {} secs.\n",
2424
n, fib_n, duration,
25-
)
25+
);
26+
Ok(res)
2627
}
2728
// Example: HTTP GET to http://localhost:8080/fib/42
2829
// $ curl "http://localhost:8080/fib/42"

examples/graphql.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn create_schema() -> Schema {
7373
Schema::new(QueryRoot {}, MutationRoot {})
7474
}
7575

76-
async fn handle_graphql(mut cx: Request<State>) -> Response {
76+
async fn handle_graphql(mut cx: Request<State>) -> tide::Result<Response> {
7777
let query: juniper::http::GraphQLRequest = cx
7878
.body_json()
7979
.await
@@ -87,15 +87,17 @@ async fn handle_graphql(mut cx: Request<State>) -> Response {
8787
StatusCode::BadRequest
8888
};
8989

90-
Response::new(status)
90+
let res = Response::new(status)
9191
.body_json(&response)
92-
.expect("be able to serialize the graphql response")
92+
.expect("be able to serialize the graphql response");
93+
Ok(res)
9394
}
9495

95-
async fn handle_graphiql(_: Request<State>) -> Response {
96-
Response::new(StatusCode::Ok)
96+
async fn handle_graphiql(_: Request<State>) -> tide::Result<Response> {
97+
let res = Response::new(StatusCode::Ok)
9798
.body_string(juniper::http::graphiql::graphiql_source("/graphql"))
98-
.set_header("content-type".parse().unwrap(), "text/html;charset=utf-8")
99+
.set_header("content-type".parse().unwrap(), "text/html;charset=utf-8");
100+
Ok(res)
99101
}
100102

101103
fn main() -> std::io::Result<()> {

examples/hello.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use async_std::task;
33
fn main() -> Result<(), std::io::Error> {
44
task::block_on(async {
55
let mut app = tide::new();
6-
app.at("/").get(|_| async move { "Hello, world!" });
6+
app.at("/").get(|_| async move { Ok("Hello, world!") });
77
app.listen("127.0.0.1:8080").await?;
88
Ok(())
99
})

examples/json.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ fn main() -> io::Result<()> {
1414

1515
app.at("/submit")
1616
.post(|mut req: tide::Request<()>| async move {
17-
let cat: Cat = req.body_json().await.unwrap();
17+
let cat: Cat = req.body_json().await?;
1818
println!("cat name: {}", cat.name);
1919

2020
let cat = Cat {
2121
name: "chashu".into(),
2222
};
2323

24-
tide::Response::new(StatusCode::Ok).body_json(&cat).unwrap()
24+
Ok(tide::Response::new(StatusCode::Ok).body_json(&cat)?)
2525
});
2626

2727
app.listen("127.0.0.1:8080").await?;

src/endpoint.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use std::sync::Arc;
2-
1+
use crate::response::IntoResponse;
32
use async_std::future::Future;
3+
use async_std::sync::Arc;
4+
use http_types::Result;
45

56
use crate::middleware::Next;
67
use crate::utils::BoxFuture;
7-
use crate::{response::IntoResponse, Middleware, Request, Response};
8+
use crate::{Middleware, Request, Response};
89

910
/// An HTTP request handler.
1011
///
@@ -23,8 +24,8 @@ use crate::{response::IntoResponse, Middleware, Request, Response};
2324
/// A simple endpoint that is invoked on a `GET` request and returns a `String`:
2425
///
2526
/// ```no_run
26-
/// async fn hello(_req: tide::Request<()>) -> String {
27-
/// String::from("hello")
27+
/// async fn hello(_req: tide::Request<()>) -> tide::Result<String> {
28+
/// Ok(String::from("hello"))
2829
/// }
2930
///
3031
/// fn main() {
@@ -37,8 +38,8 @@ use crate::{response::IntoResponse, Middleware, Request, Response};
3738
///
3839
/// ```no_run
3940
/// # use core::future::Future;
40-
/// fn hello(_req: tide::Request<()>) -> impl Future<Output = String> {
41-
/// futures::future::ready(String::from("hello"))
41+
/// fn hello(_req: tide::Request<()>) -> impl Future<Output = tide::Result<String>> {
42+
/// futures::future::ready(Ok(String::from("hello")))
4243
/// }
4344
///
4445
/// fn main() {
@@ -50,20 +51,23 @@ use crate::{response::IntoResponse, Middleware, Request, Response};
5051
/// Tide routes will also accept endpoints with `Fn` signatures of this form, but using the `async` keyword has better ergonomics.
5152
pub trait Endpoint<State>: Send + Sync + 'static {
5253
/// Invoke the endpoint within the given context
53-
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Response>;
54+
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Result<Response>>;
5455
}
5556

5657
pub(crate) type DynEndpoint<State> = dyn Endpoint<State>;
5758

58-
impl<State, F: Send + Sync + 'static, Fut> Endpoint<State> for F
59+
impl<State, F: Send + Sync + 'static, Fut, Res> Endpoint<State> for F
5960
where
6061
F: Fn(Request<State>) -> Fut,
61-
Fut: Future + Send + 'static,
62-
Fut::Output: IntoResponse,
62+
Fut: Future<Output = Result<Res>> + Send + 'static,
63+
Res: IntoResponse,
6364
{
64-
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Response> {
65+
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Result<Response>> {
6566
let fut = (self)(req);
66-
Box::pin(async move { fut.await.into_response() })
67+
Box::pin(async move {
68+
let res = fut.await?;
69+
Ok(res.into_response())
70+
})
6771
}
6872
}
6973

@@ -107,7 +111,7 @@ impl<E, State: 'static> Endpoint<State> for MiddlewareEndpoint<E, State>
107111
where
108112
E: Endpoint<State>,
109113
{
110-
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Response> {
114+
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Result<Response>> {
111115
let next = Next {
112116
endpoint: &self.endpoint,
113117
next_middleware: &self.middleware,

src/error.rs

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/lib.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//! # fn main() -> Result<(), std::io::Error> { block_on(async {
2121
//! #
2222
//! let mut app = tide::new();
23-
//! app.at("/").get(|_| async move { "Hello, world!" });
23+
//! app.at("/").get(|_| async move { Ok("Hello, world!") });
2424
//! app.listen("127.0.0.1:8080").await?;
2525
//! #
2626
//! # Ok(()) }) }
@@ -32,7 +32,7 @@
3232
//! # fn main() -> Result<(), std::io::Error> { block_on(async {
3333
//! #
3434
//! let mut app = tide::new();
35-
//! app.at("/").get(|req| async move { req });
35+
//! app.at("/").get(|req| async move { Ok(req) });
3636
//! app.listen("127.0.0.1:8080").await?;
3737
//! #
3838
//! # Ok(()) }) }
@@ -48,10 +48,10 @@
4848
//!
4949
//! let mut app = tide::new();
5050
//! app.at("/").get(|mut req: tide::Request<()>| async move {
51-
//! let mut counter: Counter = req.body_json().await.unwrap();
51+
//! let mut counter: Counter = req.body_json().await?;
5252
//! println!("count is {}", counter.count);
5353
//! counter.count += 1;
54-
//! tide::Response::new(http_types::StatusCode::Ok).body_json(&counter).unwrap()
54+
//! Ok(tide::Response::new(tide::http::StatusCode::Ok).body_json(&counter)?)
5555
//! });
5656
//! app.listen("127.0.0.1:8080").await?;
5757
//! #
@@ -150,7 +150,7 @@
150150
//! #[async_std::main]
151151
//! async fn main() -> Result<(), std::io::Error> {
152152
//! let mut app = tide::new();
153-
//! app.at("/").get(|req: Request<()>| async move { req.bark() });
153+
//! app.at("/").get(|req: Request<()>| async move { Ok(req.bark()) });
154154
//! app.listen("127.0.0.1:8080").await
155155
//! }
156156
//! ```
@@ -174,7 +174,6 @@
174174
#![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
175175

176176
mod endpoint;
177-
mod error;
178177
pub mod middleware;
179178
mod redirect;
180179
mod request;
@@ -186,18 +185,21 @@ pub mod prelude;
186185
pub mod server;
187186

188187
pub use endpoint::Endpoint;
189-
pub use error::{Error, Result, ResultExt};
190188
pub use redirect::redirect;
191189
pub use request::Request;
192190

191+
#[doc(inline)]
192+
pub use http_types::{Error, Result, Status};
193+
193194
#[doc(inline)]
194195
pub use middleware::{Middleware, Next};
195196
#[doc(inline)]
196197
pub use response::{IntoResponse, Response};
197198
#[doc(inline)]
198199
pub use server::{Route, Server};
199200

200-
pub use http_types;
201+
#[doc(inline)]
202+
pub use http_types as http;
201203

202204
/// Create a new Tide server.
203205
///
@@ -208,7 +210,7 @@ pub use http_types;
208210
/// # fn main() -> Result<(), std::io::Error> { block_on(async {
209211
/// #
210212
/// let mut app = tide::new();
211-
/// app.at("/").get(|_| async move { "Hello, world!" });
213+
/// app.at("/").get(|_| async move { Ok("Hello, world!") });
212214
/// app.listen("127.0.0.1:8080").await?;
213215
/// #
214216
/// # Ok(()) }) }
@@ -242,7 +244,7 @@ pub fn new() -> server::Server<()> {
242244
/// // Initialize the application with state.
243245
/// let mut app = tide::with_state(state);
244246
/// app.at("/").get(|req: Request<State>| async move {
245-
/// format!("Hello, {}!", &req.state().name)
247+
/// Ok(format!("Hello, {}!", &req.state().name))
246248
/// });
247249
/// app.listen("127.0.0.1:8080").await?;
248250
/// #

0 commit comments

Comments
 (0)