-
Notifications
You must be signed in to change notification settings - Fork 207
refactor(l1): improve error types with actionable context #6126
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
base: main
Are you sure you want to change the base?
Changes from 3 commits
8c18ef1
ce204dd
d649175
d76fed8
cdb35e7
f4b33d1
c28fa2c
8ec9e3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,64 @@ | ||
| use thiserror::Error; | ||
|
|
||
| // TODO: improve errors | ||
| #[derive(Debug, Error, PartialEq, Eq)] | ||
| #[derive(Debug, Error, PartialEq, Eq, Clone)] | ||
| pub enum RLPDecodeError { | ||
| #[error("InvalidLength")] | ||
| InvalidLength, | ||
| #[error("MalformedData")] | ||
| MalformedData, | ||
| #[error("MalformedBoolean")] | ||
| MalformedBoolean, | ||
| #[error("UnexpectedList")] | ||
| UnexpectedList, | ||
| #[error("UnexpectedString")] | ||
| UnexpectedString, | ||
| #[error("InvalidCompression")] | ||
| #[error("Invalid RLP length{}", fmt_ctx(.0))] | ||
| InvalidLength(Option<&'static str>), | ||
| #[error("Malformed RLP data{}", fmt_ctx(.0))] | ||
| MalformedData(Option<&'static str>), | ||
| #[error("Malformed boolean: expected 0x80 or 0x01, got 0x{0:02x}")] | ||
| MalformedBoolean(u8), | ||
| #[error("Expected RLP string, got list{}", fmt_ctx(.0))] | ||
| UnexpectedList(Option<&'static str>), | ||
| #[error("Expected RLP list, got string{}", fmt_ctx(.0))] | ||
| UnexpectedString(Option<&'static str>), | ||
| #[error("Invalid compression: {0}")] | ||
| InvalidCompression(#[from] snap::Error), | ||
| #[error("IncompatibleProtocol: {0}")] | ||
| #[error("Incompatible protocol: {0}")] | ||
| IncompatibleProtocol(String), | ||
| #[error("{0}")] | ||
| Custom(String), | ||
| } | ||
|
|
||
| // TODO: improve errors | ||
| fn fmt_ctx(ctx: &Option<&'static str>) -> String { | ||
| ctx.map(|c| format!(" decoding {c}")).unwrap_or_default() | ||
| } | ||
|
|
||
| impl RLPDecodeError { | ||
| pub fn invalid_length() -> Self { | ||
| Self::InvalidLength(None) | ||
| } | ||
|
|
||
| pub fn malformed_data() -> Self { | ||
| Self::MalformedData(None) | ||
| } | ||
|
|
||
| pub fn malformed_boolean(got: u8) -> Self { | ||
| Self::MalformedBoolean(got) | ||
| } | ||
|
|
||
| pub fn unexpected_list() -> Self { | ||
| Self::UnexpectedList(None) | ||
| } | ||
|
|
||
| pub fn unexpected_string() -> Self { | ||
| Self::UnexpectedString(None) | ||
| } | ||
|
|
||
| pub fn with_context(self, ctx: &'static str) -> Self { | ||
| match self { | ||
| Self::InvalidLength(_) => Self::InvalidLength(Some(ctx)), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Consider either:
|
||
| Self::MalformedData(_) => Self::MalformedData(Some(ctx)), | ||
| Self::UnexpectedList(_) => Self::UnexpectedList(Some(ctx)), | ||
| Self::UnexpectedString(_) => Self::UnexpectedString(Some(ctx)), | ||
| other => other, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Error)] | ||
| pub enum RLPEncodeError { | ||
| #[error("InvalidCompression")] | ||
| #[error("Invalid compression: {0}")] | ||
| InvalidCompression(#[from] snap::Error), | ||
| #[error("{0}")] | ||
| Custom(String), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
fmt_ctxallocates aStringon everyDisplaycall viaformat!(). In theNonecase,unwrap_or_default()returns an emptyString(heap-allocated). Since RLP decode errors can appear in P2P logging hot paths, you could avoid the allocation by inlining the formatting:#[error("Invalid RLP length{}", .0.map(|c| format!(" decoding {c}")).unwrap_or_default())]Or change the helper to return
&str:Actually the simplest fix: implement
Displaymanually for the variants that need context, writing directly to the formatter without intermediateString. But this is minor — the current approach works, it's just doing a small heap allocation per error display.