servers/http/result/
error_result.rs1use axum::Json;
16use axum::response::{IntoResponse, Response};
17use common_error::ext::ErrorExt;
18use common_error::from_err_code_msg_to_header;
19use common_error::status_code::StatusCode;
20use common_telemetry::{debug, error};
21use serde::{Deserialize, Serialize};
22
23use crate::error::status_code_to_http_status;
24
25#[derive(Serialize, Deserialize, Debug)]
26pub struct ErrorResponse {
27 code: u32,
28 error: String,
29 execution_time_ms: u64,
30}
31
32impl ErrorResponse {
33 pub fn from_error(error: impl ErrorExt) -> Self {
34 let code = error.status_code();
35 if code.should_log_error() {
36 error!(error; "Failed to handle HTTP request");
37 } else {
38 debug!("Failed to handle HTTP request, err: {:?}", error);
39 }
40 ErrorResponse {
41 code: code as u32,
42 error: error.output_msg(),
43 execution_time_ms: 0,
44 }
45 }
46
47 pub fn from_error_message(code: StatusCode, msg: String) -> Self {
48 if code.should_log_error() {
49 error!("Failed to handle HTTP request: {}", msg);
50 } else {
51 debug!("Failed to handle HTTP request: {}", msg);
52 }
53 ErrorResponse {
54 code: code as u32,
55 error: msg,
56 execution_time_ms: 0,
57 }
58 }
59
60 pub fn with_execution_time(mut self, execution_time: u64) -> Self {
61 self.execution_time_ms = execution_time;
62 self
63 }
64
65 pub fn execution_time_ms(&self) -> u64 {
66 self.execution_time_ms
67 }
68
69 pub fn code(&self) -> u32 {
70 self.code
71 }
72
73 pub fn error(&self) -> &str {
74 &self.error
75 }
76}
77
78impl IntoResponse for ErrorResponse {
79 fn into_response(self) -> Response {
80 let code = self.code;
81 let execution_time = self.execution_time_ms;
82 let new_header = from_err_code_msg_to_header(
83 code,
84 &format!(
85 "error: {}, execution_time_ms: {}",
86 self.error, execution_time
87 ),
88 );
89 let mut resp = Json(self).into_response();
90 resp.headers_mut().extend(new_header);
91
92 let status = StatusCode::from_u32(code).unwrap_or(StatusCode::Unknown);
93 let status_code = status_code_to_http_status(&status);
94
95 (status_code, resp).into_response()
96 }
97}