diff --git a/canister_templates/stable.wasm b/canister_templates/stable.wasm index c2b35ff0ea..2abe16e9e9 100644 Binary files a/canister_templates/stable.wasm and b/canister_templates/stable.wasm differ diff --git a/src/build/stable/commands/compile/candid_and_method_meta/execute.ts b/src/build/stable/commands/compile/candid_and_method_meta/execute.ts index fff4b87f3f..5e7471d838 100644 --- a/src/build/stable/commands/compile/candid_and_method_meta/execute.ts +++ b/src/build/stable/commands/compile/candid_and_method_meta/execute.ts @@ -72,7 +72,7 @@ export async function execute( ); const message = new TextDecoder('utf8').decode(memory); - throw message; + throw new Error(message); } } // env: { diff --git a/src/build/stable/commands/compile/wasm_binary/rust/stable_canister_template/src/execute_method_js.rs b/src/build/stable/commands/compile/wasm_binary/rust/stable_canister_template/src/execute_method_js.rs index 67c67d1c61..f6a36d210c 100644 --- a/src/build/stable/commands/compile/wasm_binary/rust/stable_canister_template/src/execute_method_js.rs +++ b/src/build/stable/commands/compile/wasm_binary/rust/stable_canister_template/src/execute_method_js.rs @@ -53,7 +53,7 @@ fn execute_method_js_with_result( let record_benchmarks = WASM_DATA_REF_CELL .with(|wasm_data_ref_cell| wasm_data_ref_cell.borrow().clone()) .as_ref() - .ok_or("could not convert wasm_data_ref_cell to ref")? + .ok_or("Could not convert wasm_data_ref_cell to ref")? .record_benchmarks; if record_benchmarks { diff --git a/src/lib/stable/execute_with_candid_serde.ts b/src/lib/stable/execute_with_candid_serde.ts index 5fd0d5fe31..255469d612 100644 --- a/src/lib/stable/execute_with_candid_serde.ts +++ b/src/lib/stable/execute_with_candid_serde.ts @@ -35,7 +35,7 @@ function decodeArgs( mode === 'query' || mode === 'update' ) { - return IDL.decode(paramIdlTypes, args[0]); + return idlDecode(paramIdlTypes, args[0]); } else { return []; } @@ -60,3 +60,29 @@ function encodeResultAndReply( reply({ data: unencodedResult, idlType: returnIdlType }); } + +export function idlEncode( + argTypes: Array>, + args: any[] +): Uint8Array { + try { + // TODO IDL.encode has ArrayBuffer as the return type, but it actually returns a Uint8Array + // TODO we may need to remove the new Uint8Array in the future if they address the situation + // TODO we are not sure if they will make the final type and return value an ArrayBuffer + // TODO or a Uint8Array: https://github.com/demergent-labs/azle/issues/2061 + return new Uint8Array(IDL.encode(argTypes, args)); + } catch (error) { + throw new Error(`Failed to encode Candid arguments: ${error}`); + } +} + +export function idlDecode( + retTypes: IDL.Type[], + bytes: ArrayBuffer +): JsonValue[] { + try { + return IDL.decode(retTypes, bytes); + } catch (error) { + throw new Error(`Failed to decode Candid bytes: ${error}`); + } +} diff --git a/src/lib/stable/ic_apis/call.ts b/src/lib/stable/ic_apis/call.ts index cf728b7ad7..8b6e67ca02 100644 --- a/src/lib/stable/ic_apis/call.ts +++ b/src/lib/stable/ic_apis/call.ts @@ -1,6 +1,8 @@ import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; -import { v4 } from 'uuid'; // TODO is uuid experimental? +import { v4 } from 'uuid'; + +import { idlDecode, idlEncode } from '../execute_with_candid_serde'; export async function call( canisterId: Principal | string, @@ -40,7 +42,7 @@ export async function call( } else { const idlType = returnTypeIdl === undefined ? [] : [returnTypeIdl]; - resolve(IDL.decode(idlType, result)[0] as Return); + resolve(idlDecode(idlType, result)[0] as Return); } delete globalThis._azleResolveIds[globalResolveId]; @@ -64,9 +66,7 @@ export async function call( : canisterId; const canisterIdBytes = canisterIdPrincipal.toUint8Array(); const argsRaw = - raw === undefined - ? new Uint8Array(IDL.encode(paramIdlTypes, args)) - : raw; + raw === undefined ? idlEncode(paramIdlTypes, args) : raw; const paymentString = payment.toString(); // TODO consider finally, what if deletion goes wrong diff --git a/src/lib/stable/ic_apis/notify.ts b/src/lib/stable/ic_apis/notify.ts index 59e681588b..6aee565f59 100644 --- a/src/lib/stable/ic_apis/notify.ts +++ b/src/lib/stable/ic_apis/notify.ts @@ -1,6 +1,8 @@ import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; +import { idlEncode } from '../execute_with_candid_serde'; + /** * Performs a cross-canister call without awaiting the result * @param canisterId The ID of the canister to notify @@ -35,10 +37,7 @@ export function notify( ? Principal.fromText(canisterId) : canisterId; const canisterIdBytes = canisterIdPrincipal.toUint8Array(); - const argsRaw = - raw === undefined - ? new Uint8Array(IDL.encode(paramIdlTypes, args)) - : raw; + const argsRaw = raw === undefined ? idlEncode(paramIdlTypes, args) : raw; const paymentString = payment.toString(); if (globalThis._azleIcExperimental !== undefined) { diff --git a/src/lib/stable/ic_apis/reply.ts b/src/lib/stable/ic_apis/reply.ts index 6dc14e0a9c..eadc03def2 100644 --- a/src/lib/stable/ic_apis/reply.ts +++ b/src/lib/stable/ic_apis/reply.ts @@ -1,5 +1,7 @@ import { IDL } from '@dfinity/candid'; +import { idlEncode } from '../execute_with_candid_serde'; + type ReplyInput = | { data: T; @@ -37,10 +39,8 @@ export function reply(input: ReplyInput): void { return globalThis._azleIcExperimental !== undefined ? globalThis._azleIcExperimental.replyRaw( - // @ts-ignore IDL.encode types are defined incorrectly https://github.com/demergent-labs/azle/issues/2061 - IDL.encode(idlType, data).buffer + idlEncode(idlType, data).buffer ) - : // @ts-ignore IDL.encode types are defined incorrectly https://github.com/demergent-labs/azle/issues/2061 - globalThis._azleIcStable.replyRaw(IDL.encode(idlType, data)); + : globalThis._azleIcStable.replyRaw(idlEncode(idlType, data)); } }