Skip to content

fix: correctly map canister error calls - #11171

Open
nmattia wants to merge 1 commit into
masterfrom
nm-ic-cdk-map-error-exhaustive
Open

fix: correctly map canister error calls#11171
nmattia wants to merge 1 commit into
masterfrom
nm-ic-cdk-map-error-exhaustive

Conversation

@nmattia

@nmattia nmattia commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

This makes all the ic-cdk error mapping helpers exhaustive and ensures canister errors are reported correctly; for instance, a "insuffient cycles balance" error should not be treated as a transient error.

See code for exact behavior.

This makes all the ic-cdk error mapping helpers exhaustive and ensures
canister errors are reported correctly; for instance, a "insuffient
cycles balance" error should _not_ be treated as a transient error.

See code for exact behavior.
@nmattia nmattia changed the title fix: correcly map canister error calls fix: correctly map canister error calls Aug 17, 2026
@github-actions github-actions Bot added the fix label Aug 18, 2026
@nmattia
nmattia marked this pull request as ready for review August 18, 2026 10:07
@nmattia
nmattia requested review from a team as code owners August 18, 2026 10:07

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This pull request changes code owned by the Governance team. Therefore, make sure that
you have considered the following (for Governance-owned code):

  1. Update unreleased_changelog.md (if there are behavior changes, even if they are
    non-breaking).

  2. Are there BREAKING changes?

  3. Is a data migration needed?

  4. Security review?

How to Satisfy This Automatic Review

  1. Go to the bottom of the pull request page.

  2. Look for where it says this bot is requesting changes.

  3. Click the three dots to the right.

  4. Select "Dismiss review".

  5. In the text entry box, respond to each of the numbered items in the previous
    section, declare one of the following:

  • Done.

  • $REASON_WHY_NO_NEED. E.g. for unreleased_changelog.md, "No
    canister behavior changes.", or for item 2, "Existing APIs
    behave as before.".

Brief Guide to "Externally Visible" Changes

"Externally visible behavior change" is very often due to some NEW canister API.

Changes to EXISTING APIs are more likely to be "breaking".

If these changes are breaking, make sure that clients know how to migrate, how to
maintain their continuity of operations.

If your changes are behind a feature flag, then, do NOT add entrie(s) to
unreleased_changelog.md in this PR! But rather, add entrie(s) later, in the PR
that enables these changes in production.

Reference(s)

For a more comprehensive checklist, see here.

GOVERNANCE_CHECKLIST_REMINDER_DEDUP

@zeropath-ai

zeropath-ai Bot commented Aug 18, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 85b6a9b.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► packages/icrc-ledger-client-cdk/src/lib.rs
      Map additional IcCdkCallError variants to detailed reject codes and messages
► packages/pocket-ic/test_canister/src/canister.rs
      Expand map_call_error with new cases for CandidDecodeFailed, InsufficientLiquidCycleBalance, CallPerformFailed
► rs/nervous_system/runtime/src/lib.rs
      Extend into_reject_code_and_message handling for new error variants
► rs/nns/cmc/src/lib.rs
      Expand into_reject_code_and_message for additional error variants
► rs/nns/handlers/root/impl/src/canister_management.rs
      Format error messages with extended handling for new error variants
► rs/nns/handlers/root/interface/src/client.rs
      Handle new IcCdkCallError variants in reject code mapping
► rs/nns/sns-wasm/canister/canister.rs
      Extend into_reject_code_and_message for additional error variants
► rs/sns/governance/canister/canister.rs
      Extend into_reject_code_and_message for additional error variants
► rs/sns/swap/src/swap.rs
      CanisterCallError From IcCdkCallError mappings extended
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/rust_canisters/proxy_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/nns/handlers/root/impl/src/canister_management.rs
      Format error with new rejection code handling
► rs/nns/handlers/root/interface/src/client.rs
      Adjust return type and mapping to new error variants
► rs/nns/sns-wasm/canister/canister.rs
      Adjust into_reject_code_and_message for new error variants
► rs/sns/swap/src/swap.rs
      From IcCdkCallError mapping updated to new variants
► rs/sns/governance/canister/canister.rs
      Adjust into_reject_code_and_message for new error variants
► rs/rust_canisters/proxy_canister/src/main.rs
      From IcCdkCallError mapping updated for new variants
Bug Fix ► packages/icrc-ledger-client-cdk/src/lib.rs
      Replace some previously transient classifications with fatal or specific codes for certain errors
► rs/nervous_system/runtime/src/lib.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/cmc/src/lib.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/handlers/root/impl/src/canister_management.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/handlers/root/interface/src/client.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/sns-wasm/canister/canister.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/sns/governance/canister/canister.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/sns/swap/src/swap.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/rust_canisters/proxy_canister/src/main.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Correctly classify InsufficientLiquidCycleBalance as Unknown (no callee reject code)
Refactor ► packages/icrc-ledger-client-cdk/src/lib.rs
      Commentary updates and reclassification of error paths
► rs/nns/handlers/root/impl/src/canister_management.rs
      Commentary updates for new mapping behavior
► rs/nns/handlers/root/interface/src/client.rs
      Commentary updates for new mapping behavior
► rs/nns/sns-wasm/canister/canister.rs
      Commentary updates for new mapping behavior
► rs/sns/governance/canister/canister.rs
      Commentary updates for new mapping behavior
► rs/sns/swap/src/swap.rs
      Commentary updates for new mapping behavior
► rs/rust_canisters/proxy_canister/src/main.rs
      Commentary updates for new mapping behavior

@zeropath-ai

zeropath-ai Bot commented Aug 18, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 85b6a9b.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► packages/icrc-ledger-client-cdk/src/lib.rs
      Map additional IcCdkCallError variants to detailed reject codes and messages
► packages/pocket-ic/test_canister/src/canister.rs
      Expand map_call_error with new cases for CandidDecodeFailed, InsufficientLiquidCycleBalance, CallPerformFailed
► rs/nervous_system/runtime/src/lib.rs
      Extend into_reject_code_and_message handling for new error variants
► rs/nns/cmc/src/lib.rs
      Expand into_reject_code_and_message for additional error variants
► rs/nns/handlers/root/impl/src/canister_management.rs
      Format error messages with extended handling for new error variants
► rs/nns/handlers/root/interface/src/client.rs
      Handle new IcCdkCallError variants in reject code mapping
► rs/nns/sns-wasm/canister/canister.rs
      Extend into_reject_code_and_message for additional error variants
► rs/sns/governance/canister/canister.rs
      Extend into_reject_code_and_message for additional error variants
► rs/sns/swap/src/swap.rs
      CanisterCallError From IcCdkCallError mappings extended
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/rust_canisters/proxy_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Update map_call_error to handle more error variants
► rs/nns/handlers/root/impl/src/canister_management.rs
      Format error with new rejection code handling
► rs/nns/handlers/root/interface/src/client.rs
      Adjust return type and mapping to new error variants
► rs/nns/sns-wasm/canister/canister.rs
      Adjust into_reject_code_and_message for new error variants
► rs/sns/swap/src/swap.rs
      From IcCdkCallError mapping updated to new variants
► rs/sns/governance/canister/canister.rs
      Adjust into_reject_code_and_message for new error variants
► rs/rust_canisters/proxy_canister/src/main.rs
      From IcCdkCallError mapping updated for new variants
Bug Fix ► packages/icrc-ledger-client-cdk/src/lib.rs
      Replace some previously transient classifications with fatal or specific codes for certain errors
► rs/nervous_system/runtime/src/lib.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/cmc/src/lib.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/handlers/root/impl/src/canister_management.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/handlers/root/interface/src/client.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/nns/sns-wasm/canister/canister.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/sns/governance/canister/canister.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/sns/swap/src/swap.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/rust_canisters/proxy_canister/src/main.rs
      Correctly classify InsufficientLiquidCycleBalance as SysFatal instead of SysTransient
► rs/rosetta-api/icp/test_utils/sender_canister/src/main.rs
      Correctly classify InsufficientLiquidCycleBalance as Unknown (no callee reject code)
Refactor ► packages/icrc-ledger-client-cdk/src/lib.rs
      Commentary updates and reclassification of error paths
► rs/nns/handlers/root/impl/src/canister_management.rs
      Commentary updates for new mapping behavior
► rs/nns/handlers/root/interface/src/client.rs
      Commentary updates for new mapping behavior
► rs/nns/sns-wasm/canister/canister.rs
      Commentary updates for new mapping behavior
► rs/sns/governance/canister/canister.rs
      Commentary updates for new mapping behavior
► rs/sns/swap/src/swap.rs
      Commentary updates for new mapping behavior
► rs/rust_canisters/proxy_canister/src/main.rs
      Commentary updates for new mapping behavior

@mraszyk

mraszyk commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

a "insuffient cycles balance" error should not be treated as a transient error.

I'm not sure about this: the corresponding error code is mapped to SysTransient in the protocol for asynchronous errors and the synchronous error is reported as the return value of 2 (SysTransient) of the corresponding system API; so I wouldn't remap the reject code in the helper.

other => (RejectionCode::Unknown, other.to_string()),
// The callee replied, but the response could not be decoded into the
// expected type, so the callee did not honor its interface: a canister-side error.
CallError::CandidDecodeFailed(e) => (RejectionCode::CanisterError, e.to_string()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure about this reject code: the following comment applies here, too - Neither of these produced a response from the callee, so there is no callee-assigned reject code to report; surface them as Unknown.

@mraszyk mraszyk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The link https://internetcomputer.org/docs/references/ic-interface-spec#reject-codes does not work for me: use https://docs.internetcomputer.org/references/ic-interface-spec/https-interface/#reject-codes

There's also a reject code SYS_UNKNOWN (6) produced by the protocol which is different from Unknown meaning that the reject code could not be parsed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry if I'm beating a dead horse, but I would like to again advocate for minimizing copy & paste.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants