Files
mnote/rust/crates/mnote-web/src/error.rs
T

67 lines
1.8 KiB
Rust
Raw Normal View History

use crate::context::RequestContext;
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ErrorBody {
pub ok: bool,
pub code: &'static str,
pub message: String,
pub request_id: Option<String>,
pub trace_id: Option<String>,
}
#[derive(Debug, Clone)]
pub struct WebError {
status: StatusCode,
code: &'static str,
message: String,
request_context: Option<RequestContext>,
}
impl WebError {
pub fn new(status: StatusCode, code: &'static str, message: impl Into<String>) -> Self {
Self {
status,
code,
message: message.into(),
request_context: None,
}
}
pub fn bad_request(message: impl Into<String>) -> Self {
Self::new(StatusCode::BAD_REQUEST, "bad_request", message)
}
pub fn internal(message: impl Into<String>) -> Self {
Self::new(StatusCode::INTERNAL_SERVER_ERROR, "internal_error", message)
}
pub fn with_context(mut self, request_context: &RequestContext) -> Self {
self.request_context = Some(request_context.clone());
self
}
}
impl IntoResponse for WebError {
fn into_response(self) -> Response {
let body = ErrorBody {
ok: false,
code: self.code,
message: self.message,
request_id: self
.request_context
.as_ref()
.map(|context| context.trace.request_id.clone()),
trace_id: self
.request_context
.as_ref()
.map(|context| context.trace.trace_id.clone()),
};
(self.status, Json(body)).into_response()
}
}