Skip to content

Improve error messages when deserialising enums#1376

Open
alexdewar wants to merge 4 commits into
mainfrom
drop-serde-string-enum-dep
Open

Improve error messages when deserialising enums#1376
alexdewar wants to merge 4 commits into
mainfrom
drop-serde-string-enum-dep

Conversation

@alexdewar

Copy link
Copy Markdown
Member

Description

The error messages you get when deserialising an enum fails are currently not very informative, e.g.:

[12:10:54 ERROR muse2] Failed to load model.

Caused by:
    0: Error reading /tmp/.tmpohiso5/simple/agent_objectives.csv
    1: CSV deserialize error: record 1 (line: 2, byte: 68): invalid value: string "lcoe", expected a valid ObjectiveType string value

We use the serde_string_enum crate for performing this deserialisation, but it turns out you can just use vanilla serde to do basically the same thing, by annotating enum variants with #[serde(rename = ..., e.g.:

/// The type of objective for the agent
#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
pub enum ObjectiveType {
    /// Average cost of one unit of output commodity over its lifetime
    #[serde(rename = "lcox")]
    LevelisedCostOfX,
    /// Net present value
    #[serde(rename = "npv")]
    NetPresentValue,
}

And you get much nicer error messages!

[12:14:35 ERROR muse2] Failed to load model.

Caused by:
    0: Error reading /tmp/.tmp5QWJ5M/simple/agent_objectives.csv
    1: CSV deserialize error: record 1 (line: 2, byte: 68): unknown variant `lcoe`, expected `lcox` or `npv`

There is one downside to this alternative approach, namely that it doesn't match the string in a case insensitve manner, so where LCOX would have matched before, now only lcox will match. If this does happen though, at least the user will get an informative message about it 😄. You can add other variants that are accepted, so we could accept both lcox and LCOX (Lcox would still be rejected), but I'm not sure it's worth it.

I first introduced the serde_string_enum dependency in #105 and didn't mention the case-insensitive thing there, so it presumably wasn't a big consideration (incidentally, it hasn't been updated since).

I think the trade-off is worth it for better error messages. We can also drop two dependencies this way, which is also nice.

Closes #848.

Type of change

  • Bug fix (non-breaking change to fix an issue)
  • New feature (non-breaking change to add functionality)
  • Refactoring (non-breaking, non-functional change to improve maintainability)
  • Optimization (non-breaking change to speed up the code)
  • Breaking change (whatever its nature)
  • Documentation (improve or add documentation)

Key checklist

  • All tests pass: $ cargo test
  • The documentation builds and looks OK: $ cargo doc
  • Update release notes for the latest release if this PR adds a new feature or fixes a bug
    present in the previous release

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

I believe it was only used by the `serde_string_enum` crate (which for some reason did not hide this behind a feature flag).
Copilot AI review requested due to automatic review settings June 26, 2026 11:17
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.68%. Comparing base (88ea927) to head (a22518c).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1376   +/-   ##
=======================================
  Coverage   89.68%   89.68%           
=======================================
  Files          58       58           
  Lines        8406     8406           
  Branches     8406     8406           
=======================================
  Hits         7539     7539           
  Misses        550      550           
  Partials      317      317           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors several user-facing string enums to use vanilla serde (#[derive(Deserialize)] + #[serde(rename = "...")]) instead of serde_string_enum, improving deserialisation error messages (e.g., listing expected variants) and dropping the serde_string_enum/unicase dependencies.

Changes:

  • Replace DeserializeLabeledStringEnum usage with serde-native enum deserialisation across multiple input enums.
  • Remove serde_string_enum and unicase from the dependency tree (and update Cargo.lock accordingly).
  • Align enum variant string mappings via #[serde(rename = "...")] for clearer parse failures.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/time_slice.rs Switch TimeSliceLevel to serde renames; remove serde_string_enum import.
src/process.rs Switch FlowType to serde renames and native Deserialize.
src/commodity.rs Switch commodity-related enums to serde renames and native Deserialize.
src/agent.rs Switch ObjectiveType to serde renames and native Deserialize.
Cargo.toml Drop serde_string_enum and unicase dependencies.
Cargo.lock Remove serde_string_enum and unicase packages from the lockfile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/time_slice.rs
Comment on lines 9 to 11
use itertools::Itertools;
use serde::de::Error;
use serde::{Deserialize, Serialize};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... this breaks compilation 🤷

Comment thread Cargo.toml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error message for incorrect enum values could be improved

2 participants