自定义错误

在上一课“abort和assert”中,我们学习了如何在需要的特定情况下故意“抛出”错误。当错误被抛出后,应用程序需要解析错误信息,并以设计的方式表现,例如弹出错误模态窗口。

应用程序如何识别特定错误呢?中止代码是关键,在一个模块中,你需要管理所有中止情况,并用中止代码标识它们,将它们声明为常量:

// battle.move

/// 战斗双方之一或双方都处于战斗冷却中
const EBattleCooldown: u64 = 0;

中止代码或错误代码的命名约定是驼峰命名法,以大写字母E开头。

在特定情况下使用常量中止:

// battle.move

entry fun battle(...) {
...
    // 3. 检查战斗冷却
    let current_timestamp = clock::timestamp_ms(clock);
    assert!(core::get_castle_battle_cooldown(&attacker) < current_timestamp, EBattleCooldown);
    assert!(core::get_castle_battle_cooldown(&defender) < current_timestamp, EBattleCooldown);
...
}

core.move 中的其他中止情况:

/// 士兵数量超过限制
const ESoldierCountLimit: u64 = 0;

/// 招募士兵的资金不足
const EInsufficientTreasury: u64 = 1;

/// 战斗城堡数量不足
const ENotEnoughCastles: u64 = 2;

情况:

public(package) fun recruit_soldiers(...) {
...
    // 2. 检查数量限制
    let final_soldiers = castle_data.millitary.soldiers + count;
    assert!(final_soldiers <= get_castle_soldier_limit(castle_data.size), ESoldierCountLimit);

    // 3. 检查资金充足性
    let total_soldier_price = SOLDIER_PRICE * count;
    assert!(castle_data.economy.treasury >= total_soldier_price, EInsufficientTreasury);
...
}

public fun random_battle_target(...) {
    let total_length = vector::length<ID>(&game_store.castle_ids);
    assert!(total_length > 1, ENotEnoughCastles);
...
}

Castle.move 中,我们漏掉了一个情况,当建造城堡时,每个城堡大小都有数量限制,我们需要在build_castle 函数的开头进行数量检查。

core.move 中添加一个函数来检查每种大小城堡的数量:

public(package) fun allow_new_castle(size: u64, game_store: &GameStore): bool {
    let allow;
    if (size == CASTLE_SIZE_SMALL) {
        allow = game_store.small_castle_count < CASTLE_AMOUNT_LIMIT_SMALL;
    } else if (size == CASTLE_SIZE_MIDDLE) {
        allow = game_store.middle_castle_count < CASTLE_AMOUNT_LIMIT_MIDDLE;
    } else if (size == CASTLE_SIZE_BIG) {
        allow = game_store.big_castle_count < CASTLE_AMOUNT_LIMIT_BIG;
    } else {
        abort 0
    };
    allow
}

/// 城堡数量限制 - 小
const CASTLE_AMOUNT_LIMIT_SMALL : u64 = 500;
/// 城堡数量限制 - 中
const CASTLE_AMOUNT_LIMIT_MIDDLE : u64 = 300;
/// 城堡数量限制 - 大
const CASTLE_AMOUNT_LIMIT_BIG : u64 = 200;

castle.move 中的 build_castle 函数中添加断言:

entry fun build_castle(...) {
    // 城堡数量检查
    assert!(core::allow_new_castle(size, game_store), ECastleAmountLimit);
...
}

const ECastleAmountLimit: u64 = 0;