Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Интеграции

Опциональные флаги функций добавляют конверсии From<...> из популярных сторонних типов ошибок в masterror::Error, так что один ? в месте вызова даёт классифицированную ошибку со структурированными метаданными. Каждая конверсия выбирает стабильный AppErrorKind и присоединяет телеметрические поля (никогда — секреты) для наблюдаемости.

Матрица конверсий

ФлагИсходный типРезультирующий AppErrorKind
sqlxsqlx_core::error::ErrorNotFound, Conflict, Validation, Timeout, DependencyUnavailable, Config, BadRequest, Serialization, Deserialization, Network, Database, Internal
sqlx-migratesqlx::migrate::MigrateErrorDatabase (с метаданными фазы миграции)
redisredis::RedisErrorCache (по умолчанию), Timeout, DependencyUnavailable
reqwestreqwest::ErrorTimeout, Network, RateLimited, DependencyUnavailable, ExternalApi
validatorvalidator::ValidationErrorsValidation
configconfig::ConfigErrorConfig (с метаданными config.phase)
tokiotokio::time::error::ElapsedTimeout
serde_jsonserde_json::ErrorSerialization (I/O), Deserialization (синтаксис/данные/EOF)
teloxideteloxide_core::RequestErrorExternalApi, Unauthorized, RateLimited, Network, Deserialization, Internal
init-datainit_data_rs::InitDataErrorTelegramAuth
tonicmasterror::Errortonic::Statusисходящее отображение, см. ниже
multipartaxum::extract::multipart::MultipartErrorBadRequest (см. Веб-фреймворки)

sqlx и sqlx-migrate

sqlx зависит только от sqlx-core (без драйверов, без TLS). Ключевые отображения:

  • Error::RowNotFoundNotFound
  • Таймаут пула → Timeout; закрытый пул и сбои I/O → DependencyUnavailable; ошибки TLS → Network
  • Нарушения ограничений классифицируются по виду ошибки sqlx: нарушения уникальности и внешних ключей → Conflict, нарушения not-null / check → Validation, всё остальное → Database
  • Кодирование → Serialization, декодирование → Deserialization

Ошибки базы данных сохраняют SQLSTATE и имена ограничений в метаданных. Известные коды SQLSTATE переопределяют публичный AppCode: 23505USER_ALREADY_EXISTS, 23503CONFLICT, 23502/23514VALIDATION. Транзиентные SQLSTATE (40001 — сбой сериализации, 55P03 — блокировка недоступна) присоединяют подсказки для повторных попыток.

use masterror::{AppErrorKind, Error};

async fn load_user(pool: &sqlx::PgPool, id: i64) -> Result<User, Error> {
    let user = sqlx::query_as::<_, User>("SELECT * FROM users WHERE id = $1")
        .bind(id)
        .fetch_one(pool)
        .await?;          // RowNotFound becomes AppErrorKind::NotFound
    Ok(user)
}

sqlx-migrate подтягивает полный sqlx (всё ещё без функций по умолчанию) и отображает sqlx::migrate::MigrateError в Database, записывая фазу и версию миграции в метаданные.

redis

Все значения redis::RedisError по умолчанию отображаются в Cache; ошибки с характером таймаута становятся Timeout, а сбои соединения — DependencyUnavailable. Категория и код ошибки сохраняются в метаданных.

reqwest

Рассматривает reqwest как клиент внешнего HTTP API:

  • is_timeout()Timeout
  • is_connect() / is_request()Network
  • Ошибки HTTP-статусов: 429RateLimited, 408Timeout, 5xxDependencyUnavailable, остальные → ExternalApi
  • всё остальное → ExternalApi

Метаданные записывают конечную точку, статус и низкоуровневые флаги; URL помечается для хеширования/редактирования в публичных полезных нагрузках.

validator

validator::ValidationErrorsValidation, с агрегированным контекстом в метаданных: имена невалидных полей (validation.fields), количество полей и ошибок, а также первые коды валидации (validation.codes):

use masterror::AppResult;
use validator::Validate;

#[derive(Validate)]
struct Payload {
    #[validate(length(min = 5))]
    name: String
}

fn check(p: &Payload) -> AppResult<()> {
    p.validate()?;      // ValidationErrors -> AppErrorKind::Validation
    Ok(())
}

config, tokio, serde_json

  • config::ConfigErrorConfig, с полем метаданных config.phase (not_found, file_parse, type, …), идентифицирующим стадию сбоя.
  • tokio::time::error::ElapsedTimeout с полем метаданных timeout.source = "tokio::time::timeout". Ошибка не несёт собственного сообщения, поэтому клиенты видят фиксированный заголовок вида "Operation timed out".
  • serde_json::Error классифицируется через Error::classify(): I/O → Serialization; синтаксис, данные и EOF → Deserialization.

teloxide

Отображение teloxide_core::RequestError:

ВариантAppErrorKind
ApiExternalApi (невалидный токен → Unauthorized)
MigrateToChatIdExternalApi
RetryAfterRateLimited
NetworkNetwork
InvalidJsonDeserialization
IoInternal

init-data (Telegram Mini Apps)

Каждый вариант init_data_rs::InitDataError (отсутствующий/невалидный хеш, истёкшая полезная нагрузка, сбои подписи) отображается в TelegramAuth, отделяя сбои аутентификации Mini App от обычных некорректных запросов.

tonic (исходящий gRPC)

tonic конвертирует в обратном направлении: masterror::Errortonic::Status через From. AppCode отображается на канонический tonic::Code через ту же таблицу CODE_MAPPINGS, что используется для HTTP. Статус несёт записи метаданных app-code, app-http-status и app-problem-type, а также подсказки о повторных попытках и www-authenticate, если они заданы. У редактируемых ошибок сообщение заменяется меткой вида, а метаданные удаляются.

use masterror::AppError;
use tonic::{Code, Status};

let status = Status::from(AppError::not_found("missing"));
assert_eq!(status.code(), Code::NotFound);

frontend (WASM / браузер)

Флаг frontend добавляет trait masterror::frontend::BrowserConsoleExt для AppError и ErrorResponse на базе wasm-bindgen:

  • to_js_value() — сериализовать ошибку в wasm_bindgen::JsValue
  • log_to_browser_console() — вывести её через console.error

Оба метода работают на целевых платформах wasm32; на нативных платформах они возвращают BrowserConsoleError::UnsupportedTarget. Режимы сбоя (отсутствие консоли, невызываемый console.error, сбой сериализации) покрыты enum BrowserConsoleError.

use masterror::{AppError, frontend::BrowserConsoleExt};

let err = AppError::not_found("user not found");
err.log_to_browser_console()?;

turnkey

Флаг turnkey предоставляет небольшую стабильную доменную таксономию в masterror::turnkey:

TurnkeyErrorKindAppErrorKind
UniqueLabelConflict
RateLimitedRateLimited
TimeoutTimeout
AuthUnauthorized
NetworkNetwork
ServiceTurnkey

TurnkeyError::new(kind, msg) строит доменную ошибку; From<TurnkeyError> for AppError и From<TurnkeyErrorKind> for AppErrorKind выполняют отображение. classify_turnkey_error(&str) эвристически классифицирует сырое сообщение провайдера (без учёта регистра, с учётом границ слов) в TurnkeyErrorKind:

use masterror::turnkey::{TurnkeyError, TurnkeyErrorKind, classify_turnkey_error};
use masterror::{AppError, AppErrorKind};

let kind = classify_turnkey_error("429 rate-limit reached");
assert_eq!(kind, TurnkeyErrorKind::RateLimited);

let app: AppError = TurnkeyError::new(kind, "quota exceeded").into();
assert_eq!(app.kind, AppErrorKind::RateLimited);

См. также: Флаги возможностей · Веб-фреймворки · Виды и коды ошибок · Наблюдаемость