Skip to content

gix-error conversion batch 1#2423

Draft
Byron wants to merge 7 commits intomainfrom
gix-error
Draft

gix-error conversion batch 1#2423
Byron wants to merge 7 commits intomainfrom
gix-error

Conversation

@Byron
Copy link
Member

@Byron Byron commented Feb 7, 2026

Batch 1 Migration Complete

11 crates migrated from thiserror to gix-error, in 11 commits:
┌────────────────┬───────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│     Crate      │                 Error types replaced                  │                            Downstream fixes                             │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-bitmap     │ 1 (ewah::decode::Error)                               │ none                                                                    │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-quote      │ 1 (ansi_c::undo::Error)                               │ none                                                                    │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-mailmap    │ 1 (parse::Error)                                      │ none                                                                    │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-fs         │ 1 (to_normal_path_components::Error)                  │ none                                                                    │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-lock       │ 1 (acquire::Error)                                    │ gix-testtools                                                           │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-path       │ 2 (relative_path::Error, realpath::Error)             │ gix-ref                                                                 │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-packetline │ 3 (encode::Error, decode::Error, decode::band::Error) │ none                                                                    │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-attributes │ 2 (name::Error, parse::Error)                         │ gix-pathspec                                                            │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-url        │ 3 (parse::Error, UrlParseError, expand_path::Error)   │ gix-transport, gix                                                      │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-hash       │ 7 (all error types)                                   │ gix-object, gix-pack, gix-odb, gix-index, gix-status, gix-protocol, gix │
├────────────────┼───────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ gix-features   │ 3 (DecompressError, CompressError, inflate::Error)    │ (included in gix-hash downstream)                                       │
└────────────────┴───────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘
Verification: cargo check -p gix passes, all 21 test suites across the 11 crates pass with 0 failures.

Tasks

  • fixup commits with correct authorship
  • thorough review

@Byron Byron force-pushed the gix-error branch 2 times, most recently from 07cbdfc to 1632f78 Compare February 8, 2026 04:49
@Byron Byron force-pushed the gix-error branch 16 times, most recently from 1427ae2 to bfaba3f Compare February 14, 2026 07:03
@Byron Byron force-pushed the gix-error branch 2 times, most recently from 8bb2abc to ec904dc Compare February 15, 2026 15:27
@Byron Byron requested a review from Copilot February 15, 2026 15:49
Copy link

Copilot AI left a comment

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 migrates 11 plumbing crates from thiserror to gix-error, implementing the project's error handling standardization strategy. The migration replaces enum-based error types with gix_error::Exn and uses message-based error construction for better composability and reduced boilerplate.

Changes:

  • Replaces thiserror enums with gix_error::Exn<gix_error::Message> or gix_error::ValidationError
  • Updates error construction to use message!() and raise() patterns
  • Adjusts downstream crates to handle new error types via .into_error() conversions
  • Replaces deprecated #[allow(missing_docs)] with #[expect(missing_docs)] throughout

Reviewed changes

Copilot reviewed 299 out of 349 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
gix-bitmap/src/ewah.rs Converts EWAH decode error from thiserror enum to gix-error ValidationError
gix-quote/src/ansi_c.rs Replaces ansi_c undo error enum with Exn
gix-mailmap/src/parse.rs Converts mailmap parse errors to ValidationError
gix-fs/src/stack.rs Updates path component error to ValidationError
gix-lock/src/acquire.rs Migrates lock acquisition errors to Exn
gix-path/src/relative_path.rs Converts RelativePath error to Exn
gix-path/src/realpath.rs Replaces realpath error enum with Exn
gix-packetline/* Converts encode/decode errors to gix-error types
gix-attributes/src/parse.rs Migrates attribute parse errors to Exn
gix-url/src/expand_path.rs Converts expand_path error to Exn
gix-hash/src/* Replaces all hash-related errors with gix-error types
gix-features/src/zlib/* Converts compression/decompression errors to Exn
gix/* Updates downstream consumers to handle new error types

Comment on lines 111 to 112
assert!(
err.to_string().contains("does not specify a path to a repository"),
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The error message assertion uses contains() which is fragile - it could break if the error message wording changes. Consider using a more specific error type check or pattern matching instead of string comparison.

Suggested change
assert!(
err.to_string().contains("does not specify a path to a repository"),
assert_eq!(
"does not specify a path to a repository",
err.to_string(),

Copilot uses AI. Check for mistakes.
Comment on lines 79 to 82
CollisionResult::Collision(digest) => Err(gix_error::message!(
"Detected SHA-1 collision attack with digest {}",
crate::ObjectId::Sha1(digest.into())
)),
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The error message exposes the full digest of a collision attack. Consider whether this information should be included in user-facing error messages, as it might aid attackers in understanding detection mechanisms.

Suggested change
CollisionResult::Collision(digest) => Err(gix_error::message!(
"Detected SHA-1 collision attack with digest {}",
crate::ObjectId::Sha1(digest.into())
)),
CollisionResult::Collision(_digest) => Err(gix_error::message(
"Detected SHA-1 collision attack"
)),

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

This Copilot code review suggestion makes no sense.

  • SHA-1 collision detection mechanisms are not secret.
  • If such a mechanism were secret, it would most likely be inadequately studied, unsafe for use, and ineffective.
  • We detect the same collisions Git detects; if we didn't, that would violate users' security and compatibility assumptions.
  • Gitoxide is free open source software.
  • Gitoxide may be used in closed source software, but the library code that detects collisions is still free open soruce software.
  • Attackers don't need help finding out which of the collisions that they have themselves produced are being detected. They already know.
  • If somehow they didn't already know, they can attempt one collision at a time to find out.
  • Omitting this information would directly prevent victims of an attack from knowing essential information that is already available to attackers.

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't even read them yet, as I am working my way through this manually anyway. But it's interesting to see what it makes up sometimes.

Comment on lines 146 to 147
tree.write_to(&mut buf)
.or_raise(|| gix_error::message("write tree to buffer"))?;
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

In benchmark code, adding error context via or_raise could impact performance measurements. Consider using direct error propagation with ? to minimize overhead in performance-critical paths.

Copilot uses AI. Check for mistakes.
Comment on lines 10 to 15
let msg = err.to_string();
assert!(
msg.starts_with(expected.as_ref()),
"Expected error starting with '{}', got '{msg}'",
expected.as_ref()
);
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The test helper now uses starts_with() instead of exact equality, which is more flexible but may hide issues where error messages have changed completely. Consider documenting why prefix matching is sufficient for these tests.

Copilot uses AI. Check for mistakes.
Comment on lines 19 to 21
let url = gix::url::parse(repo_url.to_str().unwrap().into()).map_err(gix_error::Exn::into_error)?;

println!("Url: {:?}", url.to_bstring());
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

Line 19 parses the URL and converts to error, but line 22 passes the raw repo_url string to prepare_clone. The parsed URL is only used for printing, making the parse operation redundant. Consider removing the redundant parse or using the parsed URL if possible.

Suggested change
let url = gix::url::parse(repo_url.to_str().unwrap().into()).map_err(gix_error::Exn::into_error)?;
println!("Url: {:?}", url.to_bstring());

Copilot uses AI. Check for mistakes.
Byron and others added 4 commits February 15, 2026 20:42
This allows to more conveniently create validation errors.
Replace the thiserror-derived `ewah::decode::Error` enum with
`gix_error::Exn<gix_error::ValidationError>`, using `ok_or_raise()` for
Option-based error creation.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Replace the thiserror-derived `ansi_c::undo::Error` enum with
`gix_error::Exn<gix_error::ValidationError>`, converting the `Error::new()`
factory and variant constructors to `message!()` calls.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Replace the thiserror-derived `parse::Error` enum with
`gix_error::Exn<gix_error::ValidationError>`. Tests converted from
variant pattern matching to string-based assertions.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Byron and others added 3 commits February 15, 2026 20:42
Replace the thiserror-derived `to_normal_path_components::Error`
enum with `gix_error::Exn<gix_error::Message>`.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Replace the thiserror-derived `acquire::Error` enum with
`gix_error::Exn<gix_error::Message>`. The manually-implemented
`commit::Error<T>` is unchanged.

Also fix gix-testtools for the new error type.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Replace the thiserror-derived `relative_path::Error` and
`realpath::Error` enums with `gix_error::Exn<gix_error::Message>`.

Also fix downstream gix-ref for the changed error type.

Co-Authored-By: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
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.

2 participants