servers/http/result/
error_result.rsuse axum::response::{IntoResponse, Response};
use axum::Json;
use common_error::ext::ErrorExt;
use common_error::from_err_code_msg_to_header;
use common_error::status_code::StatusCode;
use common_telemetry::{debug, error};
use serde::{Deserialize, Serialize};
use crate::error::status_code_to_http_status;
#[derive(Serialize, Deserialize, Debug)]
pub struct ErrorResponse {
code: u32,
error: String,
execution_time_ms: u64,
}
impl ErrorResponse {
pub fn from_error(error: impl ErrorExt) -> Self {
let code = error.status_code();
if code.should_log_error() {
error!(error; "Failed to handle HTTP request");
} else {
debug!("Failed to handle HTTP request, err: {:?}", error);
}
Self::from_error_message(code, error.output_msg())
}
pub fn from_error_message(code: StatusCode, msg: String) -> Self {
ErrorResponse {
code: code as u32,
error: msg,
execution_time_ms: 0,
}
}
pub fn with_execution_time(mut self, execution_time: u64) -> Self {
self.execution_time_ms = execution_time;
self
}
pub fn execution_time_ms(&self) -> u64 {
self.execution_time_ms
}
pub fn code(&self) -> u32 {
self.code
}
pub fn error(&self) -> &str {
&self.error
}
}
impl IntoResponse for ErrorResponse {
fn into_response(self) -> Response {
let code = self.code;
let execution_time = self.execution_time_ms;
let new_header = from_err_code_msg_to_header(
code,
&format!(
"error: {}, execution_time_ms: {}",
self.error, execution_time
),
);
let mut resp = Json(self).into_response();
resp.headers_mut().extend(new_header);
let status = StatusCode::from_u32(code).unwrap_or(StatusCode::Unknown);
let status_code = status_code_to_http_status(&status);
(status_code, resp).into_response()
}
}