• Discover
  • Partner with us
  • Chapters
  • Blog

Build on Internet Computer with ICP Rust CDK

Course Introduction

Introduction
Overview of the IC ecosystem and core differences
Introduction to the Internet Computer (IC) ecosystem
Overview of the IC architecture and its components
Setting up the development environment for IC

Introduction
Creating Smart Contract
State Management 1
State Management 2
Update and Query Functions
Updating the Candid File
Testing the Contract

Creating Smart Contract for Final Project
Creating Functions 1
Creating Functions 2
Creating Functions 3
Creating Candid File
Testing and Deploying Smart Contract
Overview of the Frontend for Final Project
Explaining Frontend Code

Final Project

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

  1. Retrieve Proposal: Check if the proposal with the given key exists. If not, return NoSuchProposal.
  2. Verify Ownership: Ensure that the caller is the original creator. If not, return AccessRejected.
  3. Update Only Relevant Fields: Only description and is_active fields are updated; all others are preserved to maintain integrity.
  4. Insert Updated Proposal: Replace the existing proposal in the map and handle potential errors.
Previous
Next

Lesson discussion

Swap insights and ask questions about “Build on Internet Computer with ICP Rust CDK”.

Enroll to participate
Start the course to unlock the discussion. Enrolling helps us keep conversations relevant to learners.
WebsiteDiscoverPartner with UsBlogEvents
Discover
CoursesCircleRustSoliditySolanaWeb3 FundamentalsBlockchain Basics
CompanyAbout UsBrand GuidelineFAQsTerms of UsePrivacy PolicyGDPR NoticeCookies
Don't miss any update!

Disclaimer: The information, programs, and events provided on https://risein.com is strictly for upskilling and networking purposes related to the technical infrastructure of blockchain platforms. We do not provide financial or investment advice, nor do we make any representations regarding the value, profitability, or future price of any blockchain or cryptocurrency. Users are encouraged to conduct their own research and consult with licensed financial professionals before engaging in any investment activities. https://risein.com disclaims any responsibility for financial decisions made by users based on the information provided here.

© 2026 Rise In, All rights reserved