I have this below code, everything works expect the error_handler
. I'm not sure whats wrong. If I make post request with correct format I get 200 with response data. But on bad request I'm expecting 400 with JSON data which is not receiving. It just says 400, but doesn't return any error json data.
Expected Behavior
BAD REQ -> curl -X POST -H "Content-Type: application/json" -d '{"bad": "Someone was here"}' localhost:8080/send
status 400
{
error: String,
server_id: usize,
request_count: usize,
}
Current Behavior
BAD REQ -> curl -X POST -H "Content-Type: application/json" -d '{"bad": "Someone was here"}' localhost:8080/send
status 400
Possible Solution
I replaced .data
with .app_data
it works, but then it not able to find AppState
Code
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
}
}
error handler
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()
}
Environment
- Pop OS 20.04 LTS
- Rust Version: rustc 1.45.2 (d3fb005a3 2020-07-31)
- Actix Web Version: 2.0.0