Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add underlying error to lockfile error messages #4800

Merged
merged 1 commit into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/turborepo-ffi/src/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl From<Package> for proto::LockfilePackage {
enum Error {
#[error("error performing lockfile operation: {0}")]
Lockfile(#[from] turborepo_lockfiles::Error),
#[error("error decoding protobuf")]
#[error("error decoding protobuf: {0}")]
Copy link
Contributor

Choose a reason for hiding this comment

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

Where would I begin to look up how this is working? I'd expect this diff to contain the actual value in addition to (what I assume is) the placeholder {0}. I'm guessing that means [error(...)] (macro??) is doing something fancy under the hood. But I don't know how to search for error 🤣

(Trying to learn Rust passively alongside reading the book)

Copy link
Member Author

Choose a reason for hiding this comment

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

So it already included the value! The Error enum can be viewed as just:

enum Error {
    Lockfile(turborepo_lockfiles::Error),
    Protobuf(prost::DecodeError),
    BerryParse(turborepo_lockfiles::BerryError),
    UnsupportedPackageManager(proto::PackageManager),
}

All of the #[error(...)] and #[from] macros generate some code for us that makes this enum more ergonomic.

  • The #[error("error decoding protobuf: {0}")] line is used as a formatting string when deriving a Display implementation for the enum. To be exact it generates:
    write!( __formatter, "error decoding protobuf: {field__0}", field__0 = 0.as_display())
  • The #[from] macro generates a From implementation for us that converts the protobuf error into our enum. This is especially useful when combined with the ? syntax as it automatically attempts to convert to the correct error type.
impl std::convert::From<prost::DecodeError> for Error {
    #[allow(deprecated)]
    fn from(source: prost::DecodeError) -> Self {
        Error::Protobuf { 0: source }
    }
}

The easiest way to actually understand what a macro does is to open some code up that uses it and then use rust-analyzer's expand-macro-recursively command to see exactly what it's doing. (You can also try reading the macro source, but this takes way more time IMO)

Protobuf(#[from] prost::DecodeError),
#[error(transparent)]
BerryParse(#[from] turborepo_lockfiles::BerryError),
Expand Down
6 changes: 3 additions & 3 deletions crates/turborepo-lockfiles/src/berry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ use super::Lockfile;

#[derive(Debug, Error)]
pub enum Error {
#[error("unable to parse")]
#[error("unable to parse yaml: {0}")]
Parse(#[from] serde_yaml::Error),
#[error("unable to parse")]
#[error("unable to parse identifier: {0}")]
Identifiers(#[from] identifiers::Error),
#[error("unable to find original package in patch locator {0}")]
PatchMissingOriginalLocator(Locator<'static>),
#[error("unable to parse resolutions field")]
#[error("unable to parse resolutions field: {0}")]
Resolutions(#[from] resolution::Error),
#[error("unable to find entry for {0}")]
MissingPackageForLocator(Locator<'static>),
Expand Down
2 changes: 1 addition & 1 deletion crates/turborepo-lockfiles/src/berry/resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn tag_regex() -> &'static Regex {

#[derive(Debug, Error)]
pub enum Error {
#[error("unable to parse")]
#[error("unable to parse: {0}")]
// Boxed due to this enum variant being much larger than the others
Pest(#[from] Box<pest::error::Error<Rule>>),
#[error("unexpected end of input")]
Expand Down
2 changes: 1 addition & 1 deletion crates/turborepo-lockfiles/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub enum Error {
MissingPackage(String),
#[error("Missing version from non-workspace package: '{0}'")]
MissingVersion(String),
#[error("Unable to convert from json")]
#[error("Unable to convert from json: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Turbo doesn't support npm lockfiles without a 'packages' field")]
UnsupportedNpmVersion,
Expand Down