Files
Genarrative/server-rs/crates/module-runtime/src/errors.rs
2026-05-10 22:20:54 +08:00

193 lines
8.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 运行时领域错误。
//!
//! 错误保持运行时业务语义,例如快照版本非法、兑换码不可用或钱包余额不足。
use crate::{
MAX_BROWSE_HISTORY_BATCH_SIZE, PROFILE_FEEDBACK_CONTACT_PHONE_MAX_CHARS,
PROFILE_FEEDBACK_DESCRIPTION_MAX_CHARS, PROFILE_FEEDBACK_DESCRIPTION_MIN_CHARS,
PROFILE_FEEDBACK_EVIDENCE_MAX_BYTES, PROFILE_FEEDBACK_EVIDENCE_MAX_COUNT,
PROFILE_FEEDBACK_EVIDENCE_TOTAL_MAX_BYTES,
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RuntimeSettingsFieldError {
MissingUserId,
}
impl std::fmt::Display for RuntimeSettingsFieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingUserId => f.write_str("runtime_setting.user_id 不能为空"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RuntimeBrowseHistoryFieldError {
MissingUserId,
TooManyEntries,
}
impl std::fmt::Display for RuntimeBrowseHistoryFieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingUserId => f.write_str("browse_history.user_id 不能为空"),
Self::TooManyEntries => write!(
f,
"browse_history.entries 单次最多只允许 {} 条",
MAX_BROWSE_HISTORY_BATCH_SIZE
),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RuntimeProfileFieldError {
MissingUserId,
MissingLedgerId,
InvalidWalletAmount,
WalletAmountOverflow,
WalletBalanceOverflow,
InsufficientWalletBalance,
MissingInviteCode,
MissingRedeemCode,
RedeemCodeDisabled,
RedeemCodeUsesExhausted,
RedeemCodeNotAllowedForUser,
InvalidRedeemCodeReward,
InvalidRedeemCodeMaxUses,
InvalidInviteCodeMetadata,
InvalidUserTag,
InvalidInviteCodeValidityWindow,
MissingTaskId,
MissingTaskTitle,
MissingTaskEventKey,
MissingTrackingEventId,
MissingTrackingScopeId,
InvalidTaskCycle,
InvalidTaskScopeKind,
UnsupportedProfileTaskScopeKind,
InvalidTaskThreshold,
InvalidTaskReward,
TaskDisabled,
TaskNotClaimable,
TaskAlreadyClaimed,
MissingProductId,
MissingWorldKey,
MissingBottomTab,
MissingCheckpointSessionId,
UnknownRechargeProduct,
InvalidGameStateJson,
InvalidCurrentStoryJson,
MissingRuntimeSessionId,
RuntimeSessionMismatch {
expected_session_id: String,
actual_session_id: String,
},
NonPersistentRuntimeSnapshot,
InvalidAnalyticsCalendarDate,
MissingFeedbackDescription,
FeedbackDescriptionTooShort,
FeedbackDescriptionTooLong,
FeedbackContactPhoneTooLong,
TooManyFeedbackEvidenceItems,
InvalidFeedbackEvidenceContentType,
InvalidFeedbackEvidenceDataUrl,
FeedbackEvidenceTooLarge,
FeedbackEvidenceTotalTooLarge,
}
impl std::fmt::Display for RuntimeProfileFieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingUserId => f.write_str("profile.user_id 不能为空"),
Self::MissingLedgerId => f.write_str("profile.wallet_ledger_id 不能为空"),
Self::InvalidWalletAmount => f.write_str("profile.wallet_amount 必须大于 0"),
Self::WalletAmountOverflow => f.write_str("profile.wallet_amount 超出上限"),
Self::WalletBalanceOverflow => f.write_str("profile.wallet_balance 超出上限"),
Self::InsufficientWalletBalance => f.write_str("光点余额不足"),
Self::MissingInviteCode => f.write_str("referral.invite_code 不能为空"),
Self::MissingRedeemCode => f.write_str("兑换码不能为空"),
Self::RedeemCodeDisabled => f.write_str("兑换码已停用"),
Self::RedeemCodeUsesExhausted => f.write_str("兑换次数已用完"),
Self::RedeemCodeNotAllowedForUser => f.write_str("该兑换码不适用于当前账号"),
Self::InvalidRedeemCodeReward => f.write_str("兑换码奖励无效"),
Self::InvalidRedeemCodeMaxUses => f.write_str("兑换次数必须大于 0"),
Self::InvalidInviteCodeMetadata => {
f.write_str("邀请码 metadata 必须是合法 JSON object")
}
Self::InvalidUserTag => f.write_str("用户标签格式无效"),
Self::InvalidInviteCodeValidityWindow => f.write_str("邀请码开始时间不能晚于截止时间"),
Self::MissingTaskId => f.write_str("profile_task.task_id 不能为空"),
Self::MissingTaskTitle => f.write_str("profile_task.title 不能为空"),
Self::MissingTaskEventKey => f.write_str("profile_task.event_key 不能为空"),
Self::MissingTrackingEventId => f.write_str("tracking_event.event_id 不能为空"),
Self::MissingTrackingScopeId => f.write_str("tracking_event.scope_id 不能为空"),
Self::InvalidTaskCycle => f.write_str("profile_task.cycle 无效"),
Self::InvalidTaskScopeKind => f.write_str("profile_task.scope_kind 无效"),
Self::UnsupportedProfileTaskScopeKind => {
f.write_str("个人任务 scope_kind 首版仅支持 user")
}
Self::InvalidTaskThreshold => f.write_str("profile_task.threshold 必须大于 0"),
Self::InvalidTaskReward => f.write_str("profile_task.reward_points 必须大于 0"),
Self::TaskDisabled => f.write_str("任务已停用"),
Self::TaskNotClaimable => f.write_str("任务尚未达成"),
Self::TaskAlreadyClaimed => f.write_str("任务奖励已领取"),
Self::MissingProductId => f.write_str("recharge.product_id 不能为空"),
Self::MissingWorldKey => f.write_str("profile.world_key 不能为空"),
Self::MissingBottomTab => f.write_str("runtime_snapshot.bottom_tab 不能为空"),
Self::MissingCheckpointSessionId => f.write_str("checkpoint.session_id 不能为空"),
Self::UnknownRechargeProduct => f.write_str("recharge.product_id 不存在"),
Self::InvalidGameStateJson => {
f.write_str("runtime_snapshot.game_state 必须是合法 JSON")
}
Self::InvalidCurrentStoryJson => {
f.write_str("runtime_snapshot.current_story 必须是合法 JSON object 或 null")
}
Self::MissingRuntimeSessionId => {
f.write_str("服务端运行时快照缺少 runtimeSessionId无法创建 checkpoint")
}
Self::RuntimeSessionMismatch { .. } => {
f.write_str("checkpoint sessionId 与服务端运行时快照不一致")
}
Self::NonPersistentRuntimeSnapshot => {
f.write_str("预览或测试运行态不能创建正式 checkpoint")
}
Self::InvalidAnalyticsCalendarDate => {
f.write_str("analytics_date_dimension.calendar_date 必须是合法 YYYY-MM-DD 日期")
}
Self::MissingFeedbackDescription => f.write_str("反馈问题描述不能为空"),
Self::FeedbackDescriptionTooShort => write!(
f,
"请填写{}个字以上的问题描述",
PROFILE_FEEDBACK_DESCRIPTION_MIN_CHARS
),
Self::FeedbackDescriptionTooLong => write!(
f,
"问题描述不能超过 {} 字",
PROFILE_FEEDBACK_DESCRIPTION_MAX_CHARS
),
Self::FeedbackContactPhoneTooLong => write!(
f,
"联系电话不能超过 {} 字",
PROFILE_FEEDBACK_CONTACT_PHONE_MAX_CHARS
),
Self::TooManyFeedbackEvidenceItems => {
write!(f, "最多上传{}张凭证", PROFILE_FEEDBACK_EVIDENCE_MAX_COUNT)
}
Self::InvalidFeedbackEvidenceContentType => f.write_str("反馈凭证只支持图片类型"),
Self::InvalidFeedbackEvidenceDataUrl => f.write_str("反馈凭证图片数据无效"),
Self::FeedbackEvidenceTooLarge => write!(
f,
"单张反馈凭证不能超过 {} bytes",
PROFILE_FEEDBACK_EVIDENCE_MAX_BYTES
),
Self::FeedbackEvidenceTotalTooLarge => write!(
f,
"反馈凭证总大小不能超过 {} bytes",
PROFILE_FEEDBACK_EVIDENCE_TOTAL_MAX_BYTES
),
}
}
}