Proposal
The errors thrown by canisters on the IC should include the specific error code dictating why the error was thrown in addition to the reject code.
Many of us wanting to build robust systems know there are different reasons why an inter-canister call might fail, and some of our workflows (integrations between canisters) might expect these errors. However, there are some types of errors that canister may expect, and others that canisters will never expect, which should be caught and alerted to the developing team ASAP.
The IC reject codes are too broad and categorical (only 1-6) for canisters to know exactly why a message or process failed, and needing to programmatically parse through the reject text of an error to figure out what happened is not only burdensome, it’s a fragile solution - any updates to the text error message could be considered a breaking change.
Background
On the IC, when canisters make inter-canister calls there’s a chance of these calls failing for one of many reasons.
These reasons, or ErrorCode
s can be found here
When an inter-canister call throws an error on the IC, canisters are currently only explicitly exposed to reject codes
You also receive different error messages if calling a canister from outside the IC vs. from a canister (on the IC). For example, let’s take the following case calling a canister from outside the IC.
These come with accompanying “reject text” error messages that one has to parse through in order to extract the error code. For example, in the case below parsing the reject text you’ll find a 501.
Error: Call was rejected:
Request ID: 6c6d2f761b741…9866dcd61e900cb
Reject code: 4
Reject text: IC0501: Canister jjmme-aqaaa-aaaai-ab5ya-cai is out of cycles: requested 893853709998 cycles but the available balance is 893857809998 cycles and the freezing threshold 2057103111 cycles
However, if I’m communicating from a canister in Motoko and I catch an Error
object, I can call Error.code
to get the reject code or call Error.message(error)
to get the reject text. That reject text for the same error looks like this:
Canister jjmme-aqaaa-aaaai-ab5ya-cai is out of cycles: requested 893853709998 cycles but the available balance is 893857809998 cycles and the freezing threshold 2057103111 cycles
Another example of the error messages not providing an error code with the reject text. For example, in the case what should be a 512 (CanisterInvalidController) a canister parsing the Error
with Error.message(error)
will get
Only the controllers of the canister r7inp-6aaaa-aaaaa-aaabq-cai can control it.
Canister's controllers: rwlgt-iiaaa-aaaaa-aaaaa-cai 7ynmh-argba-5k6vi-75frw-kfqpa-3xtca-nmzk3-hrmvb-fydxk-w4a4k-2ae
Sender's ID: rkp4c-7iaaa-aaaaa-aaaca-cai