From 3d4ef9dc32fc8f976dca84fb2df616155baf4f39 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 24 Aug 2021 12:42:10 +0200 Subject: [PATCH] Document how to implement `IntoResponse` for custom error type (#258) Fixes https://github.com/tokio-rs/axum/issues/249 --- CHANGELOG.md | 1 + src/response/mod.rs | 53 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2147c125..e6a2e4af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased - **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255)) +- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258)) # 0.2.0 (23. August, 2021) diff --git a/src/response/mod.rs b/src/response/mod.rs index 90991ca6..e1eb9478 100644 --- a/src/response/mod.rs +++ b/src/response/mod.rs @@ -32,8 +32,57 @@ pub use self::{headers::Headers, redirect::Redirect, sse::Sse}; /// You generally shouldn't have to implement `IntoResponse` manually, as axum /// provides implementations for many common types. /// -/// A manual implementation should only be necessary if you have a custom -/// response body type: +/// However it might be necessary if you have a custom error type that you want +/// to return from handlers: +/// +/// ```rust +/// use axum::{ +/// Router, +/// body::Body, +/// handler::get, +/// http::{Response, StatusCode}, +/// response::IntoResponse, +/// }; +/// +/// enum MyError { +/// SomethingWentWrong, +/// SomethingElseWentWrong, +/// } +/// +/// impl IntoResponse for MyError { +/// type Body = Body; +/// type BodyError = ::Error; +/// +/// fn into_response(self) -> Response { +/// let body = match self { +/// MyError::SomethingWentWrong => { +/// Body::from("something went wrong") +/// }, +/// MyError::SomethingElseWentWrong => { +/// Body::from("something else went wrong") +/// }, +/// }; +/// +/// Response::builder() +/// .status(StatusCode::INTERNAL_SERVER_ERROR) +/// .body(body) +/// .unwrap() +/// } +/// } +/// +/// // `Result` can now be returned from handlers +/// let app = Router::new().route("/", get(handler)); +/// +/// async fn handler() -> Result<(), MyError> { +/// Err(MyError::SomethingWentWrong) +/// } +/// # async { +/// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); +/// # }; +/// ``` +/// +/// Or if you have a custom body type you'll also need to implement +/// `IntoResponse` for it: /// /// ```rust /// use axum::{