Build on Internet Computer with ICP Rust CDK
Creating Functions 2
Implementing Error Handling and the edit_proposal Function in Our Smart Contract
In our previous lesson, we built the initial query and update functions for our proposal system. In this lesson, we enhance our system by introducing robust error handling using enums, and we implement the logic for editing proposals.
Step 1: Defining Enumerations for Logic and Errors
Choice Enum
We define the Choice enum to represent a vote on a proposal. It includes:
- Approve
- Reject
- Pass
Each of these choices will be used to update the corresponding vote count in a proposal.
#[derive(CandidType, Deserialize)]
pub enum Choice {
Approve,
Reject,
Pass,
}
VoteError Enum
We introduce VoteError to handle various error scenarios in a structured manner:
#[derive(CandidType, Deserialize)]
pub enum VoteError {
AlreadyVoted,
ProposalIsNotActive,
NoSuchProposal,
AccessRejected,
UpdateError,
}
These help signal issues such as unauthorized access, missing proposals, or unknown update failures.
Step 2: Implementing the edit_proposal Update Function
Only the creator (owner) of a proposal can edit it. Here's how the function works:
#[update]
fn edit_proposal(key: u64, new_data: CreateProposal) -> Result<(), VoteError> {
PROPOSAL_MAP.with(|p| {
let mut p = p.borrow_mut();
// Retrieve existing proposal
let old = match p.get(&key) {
Some(proposal) => proposal.clone(),
None => return Err(VoteError::NoSuchProposal),
};
// Check if the caller is the owner
if ic_cdk::caller() != old.owner {
return Err(VoteError::AccessRejected);
}
// Build updated proposal using the new description and is_active fields
let updated = Proposal {
description: new_data.description,
approve: old.approve,
reject: old.reject,
pass: old.pass,
is_active: new_data.is_active,
voted: old.voted.clone(),
owner: old.owner,
};
// Insert the updated proposal
let result = p.insert(key, updated);
match result {
Some(_) => Ok(()),
None => Err(VoteError::UpdateError),
}
})
}
Step 3: Summary of Logic
- Retrieve Proposal: Check if the proposal with the given key exists. If not, return NoSuchProposal.
- Verify Ownership: Ensure that the caller is the original creator. If not, return AccessRejected.
- Update Only Relevant Fields: Only description and is_active fields are updated; all others are preserved to maintain integrity.
- Insert Updated Proposal: Replace the existing proposal in the map and handle potential errors.
Comments
You need to enroll in the course to be able to comment!