Description
Motivation
@solana/programs
exports a function called isProgramError
that you can use to discern whether an error is a custom program error belonging to a certain program at a certain index of a transaction message.
Example use case
When the error in question originates from a cross-program invocation (ie. an inner instruction) and you use that error with this method, there is an opportunity for confusion, detailed below.
Details
Consider this failed transaction. The index of the failure points to instruction #4
(ie. the instruction at index 3).
{
"value": [{
"confirmationStatus": "finalized",
"confirmations": null,
"err": {
"InstructionError": [ 3, { "Custom": 6038 } ]
},
"slot": 323282082,
"status": {
"Err": {
"InstructionError": [ 3, { "Custom": 6038 } ]
}
}
}]
}
This is a bit disingenuous because the error didn't actually emanate from instruction #4
(program JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4
), it came from instruction #4.5
(program whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
). If you tried to decode this as a program error of JUP6Lk...
if (isProgramError(
error,
transactionMessage,
address('JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'),
TickArraySequenceInvalidIndex.code,
)) {
// ...
}
…you will get the wrong result. That method will return false
instead of true
because of the wrong choice of programAddress
.
Given the existing situation (ie. the server does not vend the address of the program that threw the error) developers have no choice but to parse logs to try to figure out the program from which the custom error came.