How to return Result<ok, error> in Rust (edited)

I’m trying to fix errors inside my Rust canister in the following function

#[update]
fn register(add_user: AddUser) → Result<User, String> {
let principal = ic_cdk::caller();
let user_device_store = storage::get_mut::();
if !user_device_store.contains_key(&principal) {
return Err(“This device is already registered”.to_string());
} else {
let user_store = storage::get_mut::();
let new_user = User {
id: 0,
email: add_user.email,
username: add_user.username,
image: “”.to_string(),
};

user_device_store.insert(principal, 0);
user_store.insert(0, new_user.clone());
return Ok(new_user.clone());

}
}

my .did file
type Result = variant {
err: text;
ok: user;
};

type add_user = record {
email: text;
username: text;
};

type user = record {
id: nat32;
email: text;
username: text;
image: text;
};

service : {
“get_users”: () → (vec user) query;
“register”: (add_user) → (Result);
}

But when i call the function from the frontend i get the following console error
Error: Cannot find field hash 3456837
at VariantClass.decodeValue (idl.ts:1018)
at idl.ts:1541
at Array.map ()
at Object.decode2 (idl.ts:1540)
at decodeReturnValue (actor.ts:285)
at caller (actor.ts:363)
at async register (gateway.ts:10)
the dfx console doensn’t log anything. If i check the example projects the Result<> isn’t used anywhere exept for the guard function in the asset_storage project.

Is is even possible to give this response?

1 Like

Hey, I got the same issues, with similar code. Couldn’t get it to work on the JS side, getting the “cannot find field hash” errors for both Ok() and Err() returns…

As a workaround I used this as did:

type Result = record {
    "err": text;
    "ok": bool;
};

service : {
        "update": (text) -> (Result);
}

and this for rust:

#[derive(Clone, Debug, Default, CandidType, Deserialize)]
struct Res {
    pub ok: bool,
    pub err: String,
}

fn update(name: String) -> Res {
    let principal_id = ic_cdk::caller();
    let id_store = storage::get_mut::<IdStore>();
    let profile_store = storage::get_mut::<ProfileStore>();

    let mut response = Res::default();

    if id_store.contains_key(&name) {
        response.ok = false;
        response.err = [...] <--- cant paste quotes but text goes here

        return response;
    }

    let mut profile = Profile::default();
    profile.name = name.clone();

    id_store.insert(name.clone(), principal_id.clone());
    profile_store.insert(principal_id, profile);

    response.ok = true;
    response
}
1 Like