Skip to content

Inconsistent deserialization of Leptos' Env enum #4511

@maeldroem

Description

@maeldroem

Description

Deserialization of the Env enum (leptos_config::Env) is inconsistent depending on whether it is read from the Cargo.toml file or from the LEPTOS_ENV environment variable.

Normally, when cargo-leptos reads the Cargo.toml or if main.rs reads the same file via get_configuration, the Env is derived using env_from_str, which transforms the input as lowercase before detecting whether it is Env::PROD (allowed strings: "prod", "production") or Env::DEV (allowed strings: "dev", "development").

However, when get_configuration is used in main.rs with a valid path, the environment variable are handled by get_config_from_str instead of get_config_from_env, which is used when get_configuration is passed None.

Down the call stack, it uses serde to deserialize the values (here in get_config_from_str) from the environment variables.

Serde is strict when it comes to deserialization: it only accepts same-case values as the variants from the targetted enum, therefore it will only allow the strings "PROD" and "DEV" as valid strings. If those are not provided, running a leptos app with LEPTOS_ENV set to something that would normally be valid (e.g. lowercase "prod") will result in the following panic message:

thread 'main' (180029) panicked at src/main.rs:11:54:
called `Result::unwrap()` on an `Err` value: ConfigError("enum Env does not have variant constructor prod for key `env`")

Leptos Dependencies

leptos = { version = "0.8" }
leptos_axum = { version = "0.8", optional = true }
axum = { version = "0.8.0", optional = true }

Bug reproduction steps

  1. Clone start-axum
  2. Change line 11 of main.rs to be let conf = get_configuration(Some("Cargo.toml")).unwrap();
  3. Run LEPTOS_ENV=prod cargo leptos serve
  4. Observe panic message in console

Also possible with LEPTOS_ENV=production, LEPTOS_ENV=dev, etc. as described in the description.

Next steps

I would like to make a PR, but I also want to know which approach should be used. Should the implementation of serde::Deserialize be changed on the Env enum? Should the config sources be layered in a different way? (super unfamiliar with the crate config, so I'd appreciate if somebody knew if and how this could be done so we just replace the env layer with a call to get_config_from_env() or something of the kind).

I also don't mind if somebody wants to do the PR themselves, as this could be a good first issue for somebody looking to contribute to Leptos. (oc, i'm interested to contribute, but if somebody else wants to, I don't mind either)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions