kayrx::web使用其自身的kayrx::web::error::Error类型和 kayrx::web::error::ResponseError特征处理来自Web处理程序的错误.
如果处理程序在返回Result 中的Error(指Rust std::error::Error特征) 也实现 ResultResponseError特征,kayrx::web将把该错误作为HTTP响应及其对应的kayrx::web::http::StatusCode呈现。默认情况下会生成内部服务器错误:
pub trait ResponseError {
fn error_response(&self) -> HttpResponse;
fn status_code(&self) -> StatusCode;
}
将兼容Result的Responder强制转换为HTTP响应:
impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
上面的代码中的Error是kayrx::web的错误定义,可以将实现ResponseError的任何错误自动转换.。
Actix-web提供了一些常见的非kayrx::web错误的ResponseError实现。例如,如果处理程序以io::Error响应,则该错误将转换为HttpInternalServerError:
use std::io;
fn index(_req: HttpRequest) -> io::Result<fs::NamedFile> {
Ok(fs::NamedFile::open("static/index.html")?)
}
有关ResponseError的外部实现完整列表.
这是一个实现ResponseError示例:
use kayrx::web::{error, Result};
use failure::Fail;
#\[derive(Fail, Debug)]
#\[fail(display = "my error")]
struct MyError {
name: &'static str,
}
// Use default implementation for `error_response()` method
impl error::ResponseError for MyError {}
async fn index() -> Result<&'static str, MyError> {
Err(MyError { name: "test" })
}
ResponseError有一个error_response()的默认实现,它将呈现 500 (内部服务器错误),这就是在上面执行index处理程序时将发生的情况 .
覆盖error_response()以产生更有用的结果:
use kayrx::http::ResponseBuilder;
use kayrx::web::{error, http::header, http::StatusCode, HttpResponse};
use failure::Fail;
#\[derive(Fail, Debug)]
enum MyError {
#\[fail(display = "internal error")]
InternalError,
#\[fail(display = "bad request")]
BadClientData,
#\[fail(display = "timeout")]
Timeout,
}
impl error::ResponseError for MyError {
fn error_response(&self) -> HttpResponse {
ResponseBuilder::new(self.status_code())
.set_header(header::CONTENT_TYPE, "text/html; charset=utf-8")
.body(self.to_string())
}
fn status_code(&self) -> StatusCode {
match *self {
MyError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
MyError::BadClientData => StatusCode::BAD_REQUEST,
MyError::Timeout => StatusCode::GATEWAY_TIMEOUT,
}
}
}
async fn index() -> Result<&'static str, MyError> {
Err(MyError::BadClientData)
}
kayrx::web提供了一组错误帮助函数,这些函数可用于从其他错误中生成特定的HTTP错误码。在这里,我们使用map_err将未实现ResponseError特征的MyError转换为 400(错误请求):
use kayrx::web::{error, Result};
#\[derive(Debug)]
struct MyError {
name: &'static str,
}
async fn index() -> Result<&'static str> {
let result: Result<&'static str, MyError> = Err(MyError { name: "test error" });
Ok(result.map_err(|e| error::ErrorBadRequest(e.name))?)
}
有关 可用的错误帮助程序的完整列表,请参见error模块的API文档.
kayrx::web在WARN日志级别记录所有错误。如果将应用程序的日志级别设置为DEBUG并启用RUST_BACKTRACE,则还将记录回溯。这些可以使用环境变量进行配置:
>> RUST_BACKTRACE=1 RUST_LOG=kayrx::web=debug cargo run
该Error类型使用原因的错误回溯(如果可用). 如果故障根本不提供回溯,则构造一个新的回溯,指向发生转换的点(而不是错误的根源).
考虑将应用程序产生的错误分为两大类可能是有用的:一类是面向用户的,二类不是面向用户的.
这是使用的middleware::Logger基本示例:
use kayrx::web::{error, Result};
use failure::Fail;
use log::debug;
#\[derive(Fail, Debug)]
#\[fail(display = "my error")]
pub struct MyError {
name: &'static str,
}
// Use default implementation for `error_response()` method
impl error::ResponseError for MyError {}
async fn index() -> Result<&'static str, MyError> {
let err = MyError { name: "test error" };
debug!("{}", err);
Err(err)
}
#\[kayrx::main]
async fn main() -> std::io::Result<()> {
use kayrx::web::{middleware::Logger, web, App, HttpServer};
std::env::set_var("RUST_LOG", "my_errors=debug,kayrx::web=info");
std::env::set_var("RUST_BACKTRACE", "1");
env_logger::init();
HttpServer::new(|| {
App::new()
.wrap(Logger::default())
.route("/", web::get().to(index))
})
.bind("127.0.0.1:8088")?
.run()
.await
}
[set title Kayrx / error]
[set doc-section advance-error]
[stash doc-content][require raw ../_side.html]