Интеграции
Опциональные флаги функций добавляют конверсии From<...> из популярных
сторонних типов ошибок в masterror::Error, так что один ? в месте вызова
даёт классифицированную ошибку со структурированными метаданными. Каждая
конверсия выбирает стабильный AppErrorKind и
присоединяет телеметрические поля (никогда — секреты) для наблюдаемости.
Матрица конверсий
| Флаг | Исходный тип | Результирующий AppErrorKind |
|---|---|---|
sqlx | sqlx_core::error::Error | NotFound, Conflict, Validation, Timeout, DependencyUnavailable, Config, BadRequest, Serialization, Deserialization, Network, Database, Internal |
sqlx-migrate | sqlx::migrate::MigrateError | Database (с метаданными фазы миграции) |
redis | redis::RedisError | Cache (по умолчанию), Timeout, DependencyUnavailable |
reqwest | reqwest::Error | Timeout, Network, RateLimited, DependencyUnavailable, ExternalApi |
validator | validator::ValidationErrors | Validation |
config | config::ConfigError | Config (с метаданными config.phase) |
tokio | tokio::time::error::Elapsed | Timeout |
serde_json | serde_json::Error | Serialization (I/O), Deserialization (синтаксис/данные/EOF) |
teloxide | teloxide_core::RequestError | ExternalApi, Unauthorized, RateLimited, Network, Deserialization, Internal |
init-data | init_data_rs::InitDataError | TelegramAuth |
tonic | masterror::Error → tonic::Status | исходящее отображение, см. ниже |
multipart | axum::extract::multipart::MultipartError | BadRequest (см. Веб-фреймворки) |
sqlx и sqlx-migrate
sqlx зависит только от sqlx-core (без драйверов, без TLS). Ключевые
отображения:
Error::RowNotFound→NotFound- Таймаут пула →
Timeout; закрытый пул и сбои I/O →DependencyUnavailable; ошибки TLS →Network - Нарушения ограничений классифицируются по виду ошибки
sqlx: нарушения уникальности и внешних ключей →Conflict, нарушения not-null / check →Validation, всё остальное →Database - Кодирование →
Serialization, декодирование →Deserialization
Ошибки базы данных сохраняют SQLSTATE и имена ограничений в метаданных.
Известные коды SQLSTATE переопределяют публичный
AppCode: 23505 → USER_ALREADY_EXISTS, 23503 →
CONFLICT, 23502/23514 → VALIDATION. Транзиентные 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()→Timeoutis_connect()/is_request()→Network- Ошибки HTTP-статусов:
429→RateLimited,408→Timeout,5xx→DependencyUnavailable, остальные →ExternalApi - всё остальное →
ExternalApi
Метаданные записывают конечную точку, статус и низкоуровневые флаги; URL помечается для хеширования/редактирования в публичных полезных нагрузках.
validator
validator::ValidationErrors → Validation, с агрегированным контекстом в
метаданных: имена невалидных полей (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::ConfigError→Config, с полем метаданныхconfig.phase(not_found,file_parse,type, …), идентифицирующим стадию сбоя.tokio::time::error::Elapsed→Timeoutс полем метаданныхtimeout.source = "tokio::time::timeout". Ошибка не несёт собственного сообщения, поэтому клиенты видят фиксированный заголовок вида"Operation timed out".serde_json::Errorклассифицируется черезError::classify(): I/O →Serialization; синтаксис, данные и EOF →Deserialization.
teloxide
Отображение teloxide_core::RequestError:
| Вариант | AppErrorKind |
|---|---|
Api | ExternalApi (невалидный токен → Unauthorized) |
MigrateToChatId | ExternalApi |
RetryAfter | RateLimited |
Network | Network |
InvalidJson | Deserialization |
Io | Internal |
init-data (Telegram Mini Apps)
Каждый вариант init_data_rs::InitDataError (отсутствующий/невалидный хеш,
истёкшая полезная нагрузка, сбои подписи) отображается в TelegramAuth,
отделяя сбои аутентификации Mini App от обычных некорректных запросов.
tonic (исходящий gRPC)
tonic конвертирует в обратном направлении: masterror::Error →
tonic::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::JsValuelog_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:
TurnkeyErrorKind | AppErrorKind |
|---|---|
UniqueLabel | Conflict |
RateLimited | RateLimited |
Timeout | Timeout |
Auth | Unauthorized |
Network | Network |
Service | Turnkey |
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);
См. также: Флаги возможностей · Веб-фреймворки · Виды и коды ошибок · Наблюдаемость