namespace WebDrop.Core;
public enum ErrorCode
{
BadRequest,
Unauthorized,
Forbidden,
NotJoined,
MembersFull,
ModeMismatch,
NotFound,
Conflict,
Gone,
TooLarge,
CaptchaRequired,
CaptchaUnavailable,
RateLimited,
VisitorsFull,
Sealed,
AccountRequired,
InvitationRequired,
ChannelPasswordRequired,
ChannelPasswordInvalid,
SpaceNameRequired,
}
/// 预期内的业务失败。消息只含错误码,绝不回显用户提交的内容。
public sealed class WebDropException : Exception
{
public ErrorCode Code { get; }
/// 仅在 410 日志续传失败时有值,见 api.md。
public long? OldestSeq { get; }
public WebDropException(ErrorCode code, long? oldestSeq = null) : base(code.ToWire())
{
Code = code;
OldestSeq = oldestSeq;
}
}
public static class ErrorCodes
{
public static string ToWire(this ErrorCode code) => code switch
{
ErrorCode.BadRequest => "bad_request",
ErrorCode.Unauthorized => "unauthorized",
ErrorCode.Forbidden => "forbidden",
ErrorCode.NotJoined => "not_joined",
ErrorCode.MembersFull => "members_full",
ErrorCode.ModeMismatch => "mode_mismatch",
ErrorCode.NotFound => "not_found",
ErrorCode.Conflict => "conflict",
ErrorCode.Gone => "gone",
ErrorCode.TooLarge => "too_large",
ErrorCode.CaptchaRequired => "captcha_required",
ErrorCode.CaptchaUnavailable => "captcha_unavailable",
ErrorCode.RateLimited => "rate_limited",
ErrorCode.VisitorsFull => "visitors_full",
ErrorCode.Sealed => "sealed",
ErrorCode.AccountRequired => "account_required",
ErrorCode.InvitationRequired => "invitation_required",
ErrorCode.ChannelPasswordRequired => "channel_password_required",
ErrorCode.ChannelPasswordInvalid => "channel_password_invalid",
ErrorCode.SpaceNameRequired => "space_name_required",
_ => "bad_request",
};
public static int ToStatus(this ErrorCode code) => code switch
{
ErrorCode.BadRequest => 400,
ErrorCode.Unauthorized => 401,
ErrorCode.Forbidden or ErrorCode.NotJoined or ErrorCode.MembersFull or ErrorCode.ModeMismatch => 403,
ErrorCode.NotFound => 404,
ErrorCode.Conflict => 409,
ErrorCode.Sealed => 409,
ErrorCode.SpaceNameRequired => 400,
ErrorCode.Gone => 410,
ErrorCode.TooLarge => 413,
ErrorCode.CaptchaRequired => 428,
ErrorCode.CaptchaUnavailable => 503,
ErrorCode.RateLimited => 429,
ErrorCode.VisitorsFull => 403,
ErrorCode.AccountRequired => 401,
ErrorCode.InvitationRequired or ErrorCode.ChannelPasswordRequired or ErrorCode.ChannelPasswordInvalid => 403,
_ => 400,
};
}