Skip to main content

AppError

Enum AppError 

Source
pub enum AppError {
    Business {
        code: i32,
        msg: String,
    },
    LoginExpired {
        msg: String,
    },
    DownloadUnAuth {
        msg: String,
    },
    DownloadFailed {
        msg: String,
    },
    Oss {
        code: Option<i32>,
        msg: String,
    },
    Database(String),
    Internal(String),
}
Expand description

应用层统一错误类型

封装所有业务异常,通过 [IntoResponse] 自动转换为 HTTP 响应。

§错误变体

变体HTTP 状态响应格式说明
Business200JSON {code, msg}业务逻辑错误
LoginExpired200JSON {code:401, msg}Token 过期或未登录
DownloadUnAuth403纯文本下载权限不足
DownloadFailed500纯文本文件不存在或下载失败
Oss200JSONOSS 对象存储异常
Database200JSON数据库查询/写入失败
Internal200JSON内部未知错误

§Panics

本类型不 panic。所有变体均通过 [IntoResponse] 优雅降级:

  • Database / Internal 会将完整错误栈输出到 tracing::error! 日志
  • Download* 返回纯文本以避免浏览器 blob 下载保存 JSON
  • JSON 序列化失败时有 fallback 硬编码 JSON 字符串

§从 sqlx::Error 转换

// Repository 层可直接使用 ? 传播数据库错误
let row = sqlx::query("SELECT ...").fetch_one(&pool).await?;
// sqlx::Error 自动转为 AppError::Database

Variants§

§

Business

业务异常(带码)

Fields

§code: i32
§

LoginExpired

登录过期

Fields

§

DownloadUnAuth

下载无权限(返回纯文本 403)

Fields

§

DownloadFailed

下载失败(文件不存在等,返回纯文本 500,避免 blob 客户端保存 JSON)

Fields

§

Oss

OSS 异常

Fields

§code: Option<i32>
§

Database(String)

数据库错误

§

Internal(String)

内部错误

Implementations§

Source§

impl AppError

Source

pub fn business(msg: impl Into<String>) -> Self

构造通用业务错误(错误码 500)。

§返回值

返回 AppError::Business 变体,code=500

Source

pub fn business_code(code: i32, msg: impl Into<String>) -> Self

构造指定错误码的业务错误。

§参数
  • code: 业务错误码,参见 ErrorCode 常量
  • msg: 错误描述
§返回值

返回 AppError::Business 变体。

Source

pub fn unique(field: &str) -> Self

构造唯一约束冲突错误(错误码 1002)。

消息格式:"不允许重复的{field}喵!"

§返回值

返回 AppError::Business 变体,code=1002

Source

pub fn login_expired(msg: impl Into<String>) -> Self

构造登录过期错误(错误码 401)。

§返回值

返回 AppError::LoginExpired 变体,HTTP 响应 {"code":401,"msg":"..."}

Source

pub fn download_unauth(msg: impl Into<String>) -> Self

构造下载无权限错误(HTTP 403 纯文本)。

返回纯文本而非 JSON,避免浏览器 blob 下载保存错误 JSON。

§返回值

返回 AppError::DownloadUnAuth 变体。

Source

pub fn download_failed(msg: impl Into<String>) -> Self

构造下载失败错误(HTTP 500 纯文本)。

当 legacy 下载和 OSS 下载均不可用时调用。 返回纯文本以避免浏览器 blob 下载保存 JSON。

§返回值

返回 AppError::DownloadFailed 变体。

Trait Implementations§

Source§

impl Clone for AppError

Source§

fn clone(&self) -> AppError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AppError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<Error> for AppError

自动将 sqlx::Error 转换为 AppError::Database

允许 Repository 层直接使用 ? 传播数据库错误:

let row = sqlx::query("SELECT ...").fetch_one(&pool).await?;
Source§

fn from(e: Error) -> Self

Converts to this type from the input type.
Source§

impl IntoResponse for AppError

AppError 转为 HTTP 响应。

§转换规则

变体Content-TypeHTTP 状态
Business / LoginExpired / Ossapplication/json;charset=UTF-8200
DownloadUnAuthtext/plain403
DownloadFailedtext/plain500
Database / Internalapplication/json;charset=UTF-8200

§Errors

JSON 序列化失败时有硬编码 fallback,不会 panic。

Source§

fn into_response(self) -> Response

Create a response.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T, S> Handler<IntoResponseHandler, S> for T
where T: IntoResponse + Clone + Send + 'static,

§

type Future = Ready<Response<Body>>

The type of future calling this handler returns.
§

fn call( self, _req: Request<Body>, _state: S, ) -> <T as Handler<IntoResponseHandler, S>>::Future

Call the handler with the given request.
§

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>>,

Apply a [tower::Layer] to the handler. Read more
§

fn with_state(self, state: S) -> HandlerService<Self, T, S>

Convert the handler into a [Service] by providing the state
§

impl<H, T> HandlerWithoutStateExt<T> for H
where H: Handler<T, ()>,

§

fn into_service(self) -> HandlerService<H, T, ()>

Convert the handler into a [Service] and no state.
§

fn into_make_service(self) -> IntoMakeService<HandlerService<H, T, ()>>

Convert the handler into a MakeService and no state. Read more
§

fn into_make_service_with_connect_info<C>( self, ) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C>

Convert the handler into a MakeService which stores information about the incoming connection and has no state. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more