-
Notifications
You must be signed in to change notification settings - Fork 248
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
Obtain DispatchError::Module info dynamically #453
Conversation
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.
Using this API is a bit clunky, e.g.
.wait_for_finalized_success()
.await
.map_err(|e| match e {
subxt::Error::Runtime(err) => {
let inner = err.inner();
match inner.details(self.api.client.metadata()) {
Ok(Some(details)) =>
eyre::eyre!(
"Runtime: {} -> {}: {:?}",
details.pallet(),
details.error(),
details.description(),
),
Ok(None) => eyre::eyre!("Runtime: {:?}", inner),
Err(e) => e.into(),
}
}
err => err.into(),
})?;
Perhaps we could integrate it directly into wait_for_success
, by defining a trait with fn module_error_indices(&self) -> (u8, u8)
which is implemented by the macro where at the moment you define fn details(&metadata: Metadata)
. In this context we already have the self.client
so can easily grab a reference to the metadata. Then we can construct a tuple (E, Option<ErrorMetadata>)
.
The slight wrinkle is what to do if the error cannot be resolved from the metadata, perhaps it would be better to roll that in to a None
on the right hand side rather than having a nested Option<Result<ErrorMetadata>>
or Option<Result<ErrorMetadata>>
. Because the original error is still present on the left hand side, so can still match that case with (RuntimeError::ModuleError(_), None)
Oooh interesting! I definitely agree that the API is clunky! Your suggestion has got me thinking; if we define the trait you suggest, we could extend the |
It wouldn't be a problem, except that you have to use the same pattern for every extrinsic call, so would have to use a similar helper method everywhere.
Yes that would be very nice, we are usually very interested in what the module error actually is. |
…m easier to work with
Ok, I've added a Module variant, and any Finally, if the original Module variant contains extra information beyond the pallet and error index, at present that'll be lost. When we drop backward compat we could more easily embed the new module error struct into this variant that's been added to preserve all of the info. All that said, this API is much nicer to work with! |
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.
Lovely ❤️
|
||
impl<'client, T: Config, E: Decode, Evs: Decode> TransactionProgress<'client, T, E, Evs> { | ||
impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> |
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.
Maybe worth moving to a where
-clause at this point?
Static error info is troublesome if the node you interact with uses a different pallet index for the pallet you're working with. This PR moves error info back to being obtained via runtime metadata, but keeps the
details()
fn in codegen for now to provide a nicer API for obtaining it.closes #443.