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.
We define the Choice enum to represent a vote on a proposal. It includes:
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,
}
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.
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),
}
})
}
Swap insights and ask questions about “Build on Internet Computer with ICP Rust CDK”.
Ask a question or share your thoughts about this lesson.