ok. I think I screwed something up. Now I’m getting this error in the browser console:
index.js:2 Uncaught (in promise) Error: Call was rejected:
Request ID: b7118a33259f089463a9c200c6d6e3223bb1f03043d8600f665f6549fc614b09
Reject code: 5
Reject text: Canister cxi6d-5iaaa-aaaap-qaaka-cai trapped explicitly: IDL error: too few arguments v(Nr(date:t,draft:b,emailOne:t,emailThree:t,emailTwo:t,entryTitle:t,file1MetaData:6=r(fileName:t,fileType:t,lastModified:I),file2MetaData:!6,location:t,lockTime:I,read:b,sent:b,text:t,unlockTime:I))r(dedications:t,dob:t,name:t,pob:t,preface:t)
This comes after I updated the child canisters using the strategy that you suggested @peterparker. Any idea why I would be getting a too few arguments
error? and how I’d resolve this? The canisters did upgrade without throwing any errors. But now, when I try to call the backend to retrieve the data within the canister, this error pops up.
My code:
as I previously mentioned, I decided to create an interface on my frontend that allows me to upload the wasm file and press a button that takes that wasm file and performs the necessary procedures.
front end:
import { IDL } from "@dfinity/candid";
const handleUpgrade = async () => {
let promises =[];
const wasmModule = await loadWasm();
const principalsList = await actor.getPrincipalsList();
principalsList.forEach((principal) => promises.push(upgradeJournalData(principal, wasmModule)));
await Promise.all(promises);
console.log("wasm module: ",wasmModule);
};
const upgradeJournalData = async (principal, wasmModule) => {
console.log(`Upgrading: ${principal.toText()}`);
const arg = IDL.encode([IDL.Principal], [principal]);
await actor.installCode(principal, [...arg], wasmModule);
console.log(`Done: ${principal.toText()}`);
};
function that takes the wasm file buffer and returns a Uint8Array from it.
const loadWasm = async () => {
const buffer = await getArrayBuffer(inputRef.current.files[0]);
return [...new Uint8Array(buffer)];
};
function that takes the wasm file and returns the buffer from it:
const getArrayBuffer = (inputFile) => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = () => {
resolve(reader.result);
}
reader.readAsArrayBuffer(inputFile)
});
};
Back end
public shared(msg) func installCode( userPrincipal: Principal, args: Blob, wasmModule: Blob): async() {
let callerId = msg.caller;
let profile = Trie.find(
profiles,
key(callerId),
Principal.equal
);
switch(profile){
case null{
throw Error.reject("Unauthorized access. Caller is not an admin.");
};
case ( ? existingProfile){
if (Option.get(existingProfile.userName, "null") == "admin") {
let theUserProfile = Trie.find(
profiles,
key(userPrincipal),
Principal.equal
);
switch(theUserProfile){
case null{
throw Error.reject("No profile for this principal.");
};
case ( ? existingProfile){
let userJournal = existingProfile.journal;
let journalCanisterId = Principal.fromActor(userJournal);
await ic.install_code({
arg = args;
wasm_module = wasmModule;
mode = #upgrade;
canister_id = journalCanisterId;
});
};
};
} else {
throw Error.reject("Unauthorized access. Caller is not an admin.");
}
};
};
};
The canister Id that I passed into the ic.install_code
function is the principal of the user’s canister actor. when the users’ canisters are created from the actor class, their principal is passed in as an argument.