Errors and localization
Convert domain errors into an HTTP contract and localize error messages.
Built-in HttpApiError provides a status, an error code, and a safe public message. Implement IntoResponse when you need an error schema specific to your domain.
Custom error responses#
Add serde_json = "1" to your manifest. With this converter, an action can return Result<UserView, ApiError>:
use lilyrs::http_api::{
HttpErrorCode, IntoResponse, Request, Response, ResponseBuilder,
ResponseWriteError, ResponseWriteOutcome,
};
pub enum ApiError { UserNotFound }
#[lilyrs::http_api::async_trait::async_trait]
impl IntoResponse for ApiError {
async fn write_to_response(self, response: &mut Response, request: &mut Request)
-> Result<ResponseWriteOutcome, ResponseWriteError>
{
match self {
Self::UserNotFound => {
ResponseBuilder::new().status(404, "Not Found")
.json(serde_json::json!({ "message": "Kullanıcı bulunamadı" }))
.write_to_response(response, request).await?;
Ok(ResponseWriteOutcome::rejected(Some(
HttpErrorCode::new("USER_NOT_FOUND").unwrap(),
)))
}
}
}
}UserNotFound produces 404 and {"message":"Kullanıcı bulunamadı"}. ResponseWriteOutcome::rejected classifies the result as an expected application rejection in telemetry. If the error is written successfully, the converter returns Ok; a technical write failure is distinguished by ResponseWriteError.
Public messages and internal details#
Do not expose database connection details or token contents in a public error body. A string inside HttpApiError is not automatically published verbatim. Define your public schema deliberately.
Translation catalog#
Localization is disabled by default. Choose localization_path("./locales") or localization_catalog(catalog) on the builder. JSON locale files use HttpApiError::error_code() values as keys:
{
"VALIDATION_ERROR": "Gönderilen bilgileri kontrol edin."
}Language precedence is the localization header → accept-language → en. If no translation is found, the built-in public message is used.
Catalog lifecycle#
The catalog is read during build and becomes immutable. Changing the file does not automatically reload it in a running application. A new catalog is loaded on a new application startup.
Sources for this page v0.1.0
This guide is based on the reviewed framework commit.