Skip to content

Commit

Permalink
Implement reject_code
Browse files Browse the repository at this point in the history
  • Loading branch information
dansteren committed Sep 11, 2023
1 parent dbea089 commit d202174
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 25 deletions.
27 changes: 11 additions & 16 deletions examples/rejections/canisters/rejections/index.did
Original file line number Diff line number Diff line change
@@ -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);
}
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);
}
16 changes: 12 additions & 4 deletions examples/rejections/canisters/rejections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,36 @@ export default class extends Service {

@update([], RejectionCode)
async getRejectionCodeDestinationInvalid(): Promise<RejectionCode> {
await ic.call(this.nonexistentCanister.method);
try {
await ic.call(this.nonexistentCanister.method);
} catch (error) {}

return ic.rejectCode();
}

@update([], RejectionCode)
async getRejectionCodeCanisterReject(): Promise<RejectionCode> {
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<RejectionCode> {
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<text> {
await ic.call(this.someService.reject, { args: [message] });
try {
await ic.call(this.someService.reject, { args: [message] });
} catch (error) {}

return ic.rejectMessage();
}
Expand Down
10 changes: 5 additions & 5 deletions examples/rejections/canisters/some_service/index.did
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
service : () -> {
accept : () -> (bool) query;
error : () -> (empty) query;
reject : (text) -> (empty) query;
}
service: () -> {
reject: (text) -> (empty) query;
accept: () -> (bool) query;
error: () -> (empty) query;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -118,6 +120,7 @@ pub fn generate() -> TokenStream {
#performance_counter
#print
#reject
#reject_code
#reject_message
#reply_raw
#set_certified_data
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<JSValueRef<'a>, 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)
}
}
}
33 changes: 33 additions & 0 deletions src/lib_new/ic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -871,6 +903,7 @@ export const ic: Ic = globalThis._azleIc
performanceCounter: () => {},
print: () => {},
reject: () => {},
rejectCode: () => {},
rejectMessage: () => {},
reply: () => {},
replyRaw: () => {},
Expand Down

0 comments on commit d202174

Please sign in to comment.