pub struct Error { /* private fields */ }Expand description
全局 HTTP 错误类型,贯穿整个应用。
所有字段均为私有,必须通过 Error::new 创建并经由链式 with_xxx /
add_xxx 方法配置;读取使用同名 getter(Error::status、
Error::category 等)。
内部把可选字段统一装箱到 Box<ErrorData>,将 Result<_, Error> 的
Err 变体保持在 clippy::result_large_err 128 字节限制以内。
Implementations§
Source§impl Error
impl Error
Sourcepub fn new(message: impl ToString) -> Self
pub fn new(message: impl ToString) -> Self
以错误信息创建新的 Error 实例,其余字段均为默认值。
message 接受任意 Display 类型,便于直接由外部错误包装。
Sourcepub fn with_category(self, category: impl Into<String>) -> Self
pub fn with_category(self, category: impl Into<String>) -> Self
设置错误分类(模块来源),支持链式调用。
Sourcepub fn with_sub_category(self, sub_category: impl Into<String>) -> Self
pub fn with_sub_category(self, sub_category: impl Into<String>) -> Self
设置错误子分类,支持链式调用。
Sourcepub fn with_status(self, status: u16) -> Self
pub fn with_status(self, status: u16) -> Self
设置 HTTP 状态码,支持链式调用。
Sourcepub fn with_exception(self, exception: bool) -> Self
pub fn with_exception(self, exception: bool) -> Self
标记是否为需要告警的异常级错误,支持链式调用。
只影响告警,不影响响应体是否脱敏——脱敏见 Self::with_redact。
Sourcepub fn with_redact(self, redact: bool) -> Self
pub fn with_redact(self, redact: bool) -> Self
显式控制是否对客户端隐去 message 与 extra,支持链式调用。
不调用本方法时按状态码判定:5xx 隐去、4xx 保留。
之所以要与 Self::with_exception 分开:两者是独立的轴。exception
的语义是「需要告警」,不等于「含内部细节」。此前二者被合并判定,
一个 400 + exception 的错误会回 400 {"message":"internal server error"},
状态码与文案自相矛盾,前端无从处理。
需要覆盖默认时才用它,两个方向都支持:
with_redact(true):4xx 但 message 含内部细节(如策略引擎的内部规则)with_redact(false):5xx 但 message 是可安全外露的固定文案
Sourcepub fn sub_category(&self) -> Option<&str>
pub fn sub_category(&self) -> Option<&str>
错误子分类,未设置时返回 None。
Sourcepub fn is_exception(&self) -> bool
pub fn is_exception(&self) -> bool
是否为需要告警的异常级错误;未显式设置时返回 false。
Sourcepub fn redact(&self) -> Option<bool>
pub fn redact(&self) -> Option<bool>
是否已显式设置脱敏;None 表示按状态码默认判定(见 Self::with_redact)。
Sourcepub fn from_upstream(status: u16, body: &[u8]) -> Self
pub fn from_upstream(status: u16, body: &[u8]) -> Self
由上游服务的 HTTP 错误响应重建 Error。
上游若是同样用本类型的 tibba 服务,category / sub_category / code /
extra 会被原样保留;否则退化为「把响应体当纯文本作 message」。
§为什么 status 从参数来而不是从响应体解析
状态码本来就在 HTTP 状态行上,把它再塞进 JSON body 是冗余——也正因如此
Error 的序列化形式里没有它,单纯 serde_json::from_slice 得到的 Error
状态码是 0(落到 IntoResponse 会变成 500)。这个构造函数就是那块拼图:
由调用方把状态行上的值传进来,结构化字段从 body 来。
§注意:这是上游的状态码
返回的 Error 带的是上游给的状态码,不代表本服务该回什么。直接透传给
自己的客户端通常是错的(上游 401 不等于调用方未登录)。调用方应显式
决定对外状态码,见 tibba-request 的 handle_fail 如何映射成 502。
响应体不是本类型的 JSON 时,message 取响应体文本并截断到
MAX_UPSTREAM_MESSAGE_LEN 字节——上游回一整页 HTML 错误页是常事,
整页塞进 message 只会把日志冲垮。
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Error
impl<'de> Deserialize<'de> for Error
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl Error for Error
impl Error for Error
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl IntoResponse for Error
将 Error 转换为带 JSON 响应体和 no-cache 头的 HTTP 响应。
impl IntoResponse for Error
将 Error 转换为带 JSON 响应体和 no-cache 头的 HTTP 响应。
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
Auto Trait Implementations§
impl Freeze for Error
impl RefUnwindSafe for Error
impl Send for Error
impl Sync for Error
impl Unpin for Error
impl UnsafeUnpin for Error
impl UnwindSafe for Error
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T, S> Handler<IntoResponseHandler, S> for T
impl<T, S> Handler<IntoResponseHandler, S> for T
Source§fn call(
self,
_req: Request<Body>,
_state: S,
) -> <T as Handler<IntoResponseHandler, S>>::Future
fn call( self, _req: Request<Body>, _state: S, ) -> <T as Handler<IntoResponseHandler, S>>::Future
Source§fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>where
L: Layer<HandlerService<Self, T, S>> + Clone,
<L as Layer<HandlerService<Self, T, S>>>::Service: Service<Request<Body>>,
fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>where
L: Layer<HandlerService<Self, T, S>> + Clone,
<L as Layer<HandlerService<Self, T, S>>>::Service: Service<Request<Body>>,
tower::Layer to the handler. Read moreSource§fn with_state(self, state: S) -> HandlerService<Self, T, S>
fn with_state(self, state: S) -> HandlerService<Self, T, S>
Service by providing the stateSource§impl<H, T> HandlerWithoutStateExt<T> for H
impl<H, T> HandlerWithoutStateExt<T> for H
Source§fn into_service(self) -> HandlerService<H, T, ()>
fn into_service(self) -> HandlerService<H, T, ()>
Service and no state.Source§fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, ()>>
fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, ()>>
MakeService and no state. Read moreSource§fn into_make_service_with_connect_info<C>(
self,
) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C>
fn into_make_service_with_connect_info<C>( self, ) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C>
MakeService which stores information
about the incoming connection and has no state. Read more