#1751·loco

Better error handling

Author: milesjCreated Mar 8, 2026Updated Mar 8, 2026
Labelsenhancement

Feature Request

Is your feature request related to a problem? Please describe.

Nope.

Describe the solution you'd like

Loco provides a Result and Error types for error handling, but this is very restrictive. Coming from other applications, we typically use anyhow, eros (very nice), or other similar libraries for easily bubbling up errors (especially with context).

But with Loco, this is not possible. We have to constantly use map_err on most APIs (especially ones we don't control), which is very ugly and verbose. For example:

rust
let client = BasicClient::new(ClientId::new(client_id))
    .set_client_secret(ClientSecret::new(client_secret))
    .set_auth_uri(
        AuthUrl::new(cfg.auth_url.to_string())
            .map_err(|e| loco_rs::Error::string(&format!("Invalid auth URL: {e}")))?,
    )
    .set_token_uri(
        TokenUrl::new(cfg.token_url.to_string())
            .map_err(|e| loco_rs::Error::string(&format!("Invalid token URL: {e}")))?,
    )
    .set_redirect_uri(
        RedirectUrl::new(redirect_url)
            .map_err(|e| loco_rs::Error::string(&format!("Invalid redirect URL: {e}")))?,
    );

Ideally we can just do this:

rust
let client = BasicClient::new(ClientId::new(client_id))
    .set_client_secret(ClientSecret::new(client_secret))
    .set_auth_uri(AuthUrl::new(cfg.auth_url.to_string())?)
    .set_token_uri(TokenUrl::new(cfg.token_url.to_string())?)
    .set_redirect_uri(RedirectUrl::new(redirect_url)?);

Or this if we want to preserve context:

rust
let client = BasicClient::new(ClientId::new(client_id))
    .set_client_secret(ClientSecret::new(client_secret))
    .set_auth_uri(AuthUrl::new(cfg.auth_url.to_string()).context("Invalid auth URL")?)
    .set_token_uri(TokenUrl::new(cfg.token_url.to_string()).context("Invalid token URL")?)
    .set_redirect_uri(RedirectUrl::new(redirect_url).context("Invalid redirect URL")?);

Describe alternatives you've considered

I suggest using eros for error handling. It's a super version of anyhow.

We've updated all of our internal APIs, controllers, and other "isolated" code to use eros, which has been a much nicer experience.

In some situations, we have to map eros::Result to loco_rs::Result, but this is still a nice experience.