问题描述
我有以下代码,一切正常,期望error_handler。我不知道怎么了。如果我以正确的格式发出过帐请求,则会得到200份响应数据。但是在错误的请求下,我希望400的Json数据无法接收。它只是说400,但不返回任何错误json数据。
预期行为
BAD REQ-> curl -X POST -H“ Content-Type:application / json” -d'{“ bad”:“有人在这里”}}'localhost:8080 / send
status 400
{
error: String,server_id: usize,request_count: usize,}
当前行为
BAD REQ-> curl -X POST -H“ Content-Type:application / json” -d'{“ bad”:“有人在这里”}'localhost:8080 / send 状态400
可能的解决方案
我用.data
取代了.app_data
,但是它找不到AppState
代码
pub struct MessageApp {
pub port: u16,}
impl MessageApp {
pub fn new(port: u16) -> Self {
Self{port}
}
pub async fn run(&self) -> std::io::Result<()> {
let messages = Arc::new(Mutex::new(vec![]));
println!("Starting http server: 127.0.0.1:{}",self.port);
HttpServer::new(move || {
App::new()
.data(AppState {
server_id: SERVER_COUNTER.fetch_add(1,Ordering::SeqCst),request_count: Cell::new(0),messages: messages.clone(),})
.wrap(middleware::Logger::new(LOG_FORMAT))
.service(index)
.service(
web::resource("/send")
.data(
web::JsonConfig::default()
.limit(4096)
.error_handler(post_error)
)
.route(web::post().to(post))
)
.service(clear)
})
.bind(("127.0.0.1",self.port))?
.workers(8)
.run()
.await
}
}
错误处理程序
fn post_error(err: JsonPayloadError,req: &HttpRequest) -> Error {
let extns = req.extensions();
let state = extns.get::<web::Data<AppState>>().unwrap();
let request_count = state.request_count.get() + 1;
state.request_count.set(request_count);
let post_error = PostError {
server_id: state.server_id,request_count,error: format!("{}",err),};
InternalError::from_response(err,HttpResponse::BadRequest().json(post_error)).into()
}
上下文
我只是想学习Actix
您的环境
- Pop OS 20.04 LTS
- Rust版本:rustc 1.45.2(d3fb005a3 2020-07-31)
- Actix Web版本:2.0.0
解决方法
正如我之前在可能的解决方案中所述。
在github上获得作者的帮助后。他提到我需要移出.app_data
才能解决此问题,或移至解决此问题的新版本3.0。
但是使用下面的2.0.0版本是解决方案:
HttpServer::new(move || {
App::new()
.data(AppState {
server_id: SERVER_COUNTER.fetch_add(1,Ordering::SeqCst),request_count: Cell::new(0),messages: messages.clone(),})
.wrap(middleware::Logger::new(LOG_FORMAT))
.service(index)
.service(
web::resource("/send")
.app_data(
web::JsonConfig::default().limit(4096).error_handler(post_error)
)
.route(web::post().to(post))
)
.service(clear)
})
.bind(("127.0.0.1",self.port))?
.workers(8)
.run()
.await
我提取AppState的方法也做错了。该问题已在 post_error 函数内部固定在下面。
fn post_error(err: JsonPayloadError,req: &HttpRequest) -> Error {
// let extns = req.extensions();
// let state = extns.get::<web::Data<AppState>>().unwrap();
let state = req.app_data::<web::Data<AppState>>().unwrap();
let request_count = state.request_count.get() + 1;
state.request_count.set(request_count);
let post_error = PostError {
server_id: state.server_id,request_count,error: format!("{}",err),};
InternalError::from_response(err,HttpResponse::BadRequest().json(post_error)).into()
}