From d2021740cc51f7cf462c56019860cb0457d43c14 Mon Sep 17 00:00:00 2001 From: Dan Steren Date: Mon, 11 Sep 2023 12:32:47 -0600 Subject: [PATCH] Implement reject_code --- .../rejections/canisters/rejections/index.did | 27 +++++++-------- .../rejections/canisters/rejections/index.ts | 16 ++++++--- .../canisters/some_service/index.did | 10 +++--- .../src/ic/mod.rs | 4 +++ .../src/ic/reject_code.rs | 28 ++++++++++++++++ src/lib_new/ic.ts | 33 +++++++++++++++++++ 6 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/reject_code.rs diff --git a/examples/rejections/canisters/rejections/index.did b/examples/rejections/canisters/rejections/index.did index dfb1473040..e988a2ebb0 100644 --- a/examples/rejections/canisters/rejections/index.did +++ b/examples/rejections/canisters/rejections/index.did @@ -1,16 +1,11 @@ -type ManualReply = variant { - NoError; - CanisterError; - SysTransient; - DestinationInvalid; - Unknown; - SysFatal; - CanisterReject; -}; -service : () -> { - getRejectionCodeCanisterError : () -> (ManualReply); - getRejectionCodeCanisterReject : () -> (ManualReply); - getRejectionCodeDestinationInvalid : () -> (ManualReply); - getRejectionCodeNoError : () -> (ManualReply); - getRejectionMessage : (text) -> (text); -} \ No newline at end of file +type rec_0 = variant {NoError; CanisterError; SysTransient; DestinationInvalid; Unknown; SysFatal; CanisterReject}; +type rec_1 = variant {NoError; CanisterError; SysTransient; DestinationInvalid; Unknown; SysFatal; CanisterReject}; +type rec_2 = variant {NoError; CanisterError; SysTransient; DestinationInvalid; Unknown; SysFatal; CanisterReject}; +type rec_3 = variant {NoError; CanisterError; SysTransient; DestinationInvalid; Unknown; SysFatal; CanisterReject}; +service: () -> { + getRejectionCodeNoError: () -> (rec_0); + getRejectionCodeDestinationInvalid: () -> (rec_1); + getRejectionCodeCanisterReject: () -> (rec_2); + getRejectionCodeCanisterError: () -> (rec_3); + getRejectionMessage: (text) -> (text); +} diff --git a/examples/rejections/canisters/rejections/index.ts b/examples/rejections/canisters/rejections/index.ts index 2f836634f9..d6812446da 100644 --- a/examples/rejections/canisters/rejections/index.ts +++ b/examples/rejections/canisters/rejections/index.ts @@ -35,28 +35,36 @@ export default class extends Service { @update([], RejectionCode) async getRejectionCodeDestinationInvalid(): Promise { - await ic.call(this.nonexistentCanister.method); + try { + await ic.call(this.nonexistentCanister.method); + } catch (error) {} return ic.rejectCode(); } @update([], RejectionCode) async getRejectionCodeCanisterReject(): Promise { - await ic.call(this.someService.reject, { args: ['reject'] }); + try { + await ic.call(this.someService.reject, { args: ['reject'] }); + } catch (error) {} return ic.rejectCode(); } @update([], RejectionCode) async getRejectionCodeCanisterError(): Promise { - await ic.call(this.someService.error); + try { + await ic.call(this.someService.error); + } catch (error) {} return ic.rejectCode(); } @update([text], text) async getRejectionMessage(message: text): Promise { - await ic.call(this.someService.reject, { args: [message] }); + try { + await ic.call(this.someService.reject, { args: [message] }); + } catch (error) {} return ic.rejectMessage(); } diff --git a/examples/rejections/canisters/some_service/index.did b/examples/rejections/canisters/some_service/index.did index 19b538a628..c6fa73bb53 100644 --- a/examples/rejections/canisters/some_service/index.did +++ b/examples/rejections/canisters/some_service/index.did @@ -1,5 +1,5 @@ -service : () -> { - accept : () -> (bool) query; - error : () -> (empty) query; - reject : (text) -> (empty) query; -} \ No newline at end of file +service: () -> { + reject: (text) -> (empty) query; + accept: () -> (bool) query; + error: () -> (empty) query; +} diff --git a/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/mod.rs b/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/mod.rs index 09b5764672..3a1e17d789 100644 --- a/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/mod.rs +++ b/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/mod.rs @@ -28,6 +28,7 @@ mod notify_raw; mod performance_counter; mod print; mod reject; +mod reject_code; mod reject_message; mod reply_raw; mod set_certified_data; @@ -73,6 +74,7 @@ pub fn generate() -> TokenStream { let performance_counter = performance_counter::generate(); let print = print::generate(); let reject = reject::generate(); + let reject_code = reject_code::generate(); let reject_message = reject_message::generate(); let reply_raw = reply_raw::generate(); let set_certified_data = set_certified_data::generate(); @@ -118,6 +120,7 @@ pub fn generate() -> TokenStream { #performance_counter #print #reject + #reject_code #reject_message #reply_raw #set_certified_data @@ -164,6 +167,7 @@ pub fn generate() -> TokenStream { ic.set_property("performanceCounter", context.wrap_callback2(performance_counter).unwrap()).unwrap(); ic.set_property("print", context.wrap_callback2(print).unwrap()).unwrap(); ic.set_property("reject", context.wrap_callback2(reject).unwrap()).unwrap(); + ic.set_property("rejectCode", context.wrap_callback2(reject_code).unwrap()).unwrap(); ic.set_property("rejectMessage", context.wrap_callback2(reject_message).unwrap()).unwrap(); ic.set_property("replyRaw", context.wrap_callback2(reply_raw).unwrap()).unwrap(); ic.set_property("setCertifiedData", context.wrap_callback2(set_certified_data).unwrap()).unwrap(); diff --git a/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/reject_code.rs b/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/reject_code.rs new file mode 100644 index 0000000000..f439dd8b1c --- /dev/null +++ b/src/compiler/typescript_to_rust/azle_generate_rearchitecture/src/ic/reject_code.rs @@ -0,0 +1,28 @@ +use proc_macro2::TokenStream; +use quote::quote; + +pub fn generate() -> TokenStream { + quote! { + fn reject_code<'a>( + context: &'a JSContextRef, + _this: &CallbackArg, + _args: &[CallbackArg], + ) -> Result, anyhow::Error> { + let reject_code = ic_cdk::api::call::reject_code(); + + let reject_code_as_u8 = match reject_code { + ic_cdk::api::call::RejectionCode::NoError => 0, + ic_cdk::api::call::RejectionCode::SysFatal => 1, + ic_cdk::api::call::RejectionCode::SysTransient => 2, + ic_cdk::api::call::RejectionCode::DestinationInvalid => 3, + ic_cdk::api::call::RejectionCode::CanisterReject => 4, + ic_cdk::api::call::RejectionCode::CanisterError => 5, + ic_cdk::api::call::RejectionCode::Unknown => 6, + }; + + let reject_code_as_js_value: JSValue = reject_code_as_u8.into(); + + to_qjs_value(&context, &reject_code_as_js_value) + } + } +} diff --git a/src/lib_new/ic.ts b/src/lib_new/ic.ts index 8cc1aad354..e9d5048241 100644 --- a/src/lib_new/ic.ts +++ b/src/lib_new/ic.ts @@ -2,6 +2,7 @@ import { Nat64 } from '@dfinity/candid/lib/esm/idl'; // Note: Importing IDL from import { Principal } from '@dfinity/principal'; import { IDL } from './index'; import { blob, nat, nat32, nat64, Void, Opt } from './primitives'; +import { RejectionCode } from './system_types'; import { v4 } from 'uuid'; import { CandidClass, toCandidClass } from './utils'; @@ -251,6 +252,13 @@ type Ic = { */ reject: (message: string) => void; + /** + * Returns the rejection code from the most recently executed cross-canister + * call + * @returns the rejection code + */ + rejectCode: () => RejectionCode; + /** * Returns the rejection message from the most recently executed * cross-canister call @@ -694,6 +702,30 @@ export const ic: Ic = globalThis._azleIc return IDL.decode([IDL.Nat64], performanceCounterCandidBytes)[0]; }, + rejectCode: () => { + const rejectCodeNumber = globalThis._azleIc.rejectCode(); + + switch (rejectCodeNumber) { + case 0: + return { NoError: null }; + case 1: + return { SysFatal: null }; + case 2: + return { SysTransient: null }; + case 3: + return { DestinationInvalid: null }; + case 4: + return { CanisterReject: null }; + case 5: + return { CanisterError: null }; + case 6: + return { Unknown: null }; + default: + throw Error( + `Unknown rejection code: ${rejectCodeNumber}` + ); + } + }, reply: (reply: any, type: CandidClass): void => { if (Array.isArray(type) && type.length === 0) { // return type is void @@ -871,6 +903,7 @@ export const ic: Ic = globalThis._azleIc performanceCounter: () => {}, print: () => {}, reject: () => {}, + rejectCode: () => {}, rejectMessage: () => {}, reply: () => {}, replyRaw: () => {},