You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API的Service层抛出错误时指定对应HTTP状态码?

解决方案:自定义错误类实现状态码绑定

当然可以在抛出错误时指定对应的HTTP状态码,不用改动现有分层逻辑,核心是通过自定义错误类给错误附加状态码属性,让Controller层捕获后识别并返回对应响应码。

1. 定义带状态码的自定义错误类

创建继承自原生Error的类,额外添加statusCode属性存储HTTP状态码:

class HttpError extends Error {
  statusCode: number;

  constructor(message: string, statusCode: number) {
    super(message);
    this.statusCode = statusCode;
    // 修复原型链,保证instanceof判断正常
    Object.setPrototypeOf(this, HttpError.prototype);
  }
}

2. 修改Service层,抛出带状态码的自定义错误

把原有的throw new Error()替换为自定义错误,根据业务场景匹配对应状态码:

export const loginUser = async (email: string, password: string) => {
    if (!email || !password) {
        // 字段缺失:400 请求参数错误
        throw new HttpError('All fields are required', 400);
    }

    const user = await findUser(email);

    if (!user) {
        // 用户不存在:404 资源未找到
        throw new HttpError('User does not exist', 404);
    }

    const isValid = validPassword(password, user.password.salt, user.password.hash);

    if (isValid) {
        const { refreshToken, accessToken } = issueJWT(user._id);

        return { refreshToken, accessToken };
    } else {
        // 密码错误:401 未授权
        throw new HttpError('You entered the wrong password', 401);
    }
};

3. 修改Controller层,捕获并处理自定义错误

在catch块中判断错误类型,使用自定义错误的statusCode返回响应,未知错误仍返回500:

export const login = async (req: Request, res: Response) => {
    const { email, password } = req.body;

    try {
        const { accessToken, refreshToken } = await loginUser(email, password);

        res.cookie('jwt', refreshToken, { httpOnly: true, secure: true });

        return res.status(200).json({ accessToken });
    } catch (error) {
        if (error instanceof HttpError) {
            return res.status(error.statusCode).json({ error: error.message });
        }
        // 其他未知错误返回500
        return res.status(500).json({ error: 'Internal server error' });
    }
};

补充说明

这种方式既保留了Service层(负责业务逻辑和错误定义)与Controller层(负责HTTP响应处理)的职责分离,又能精准返回对应状态码。后续新增错误场景时,只需扩展自定义错误或添加新的状态码映射即可。

内容的提问来源于stack exchange,提问作者user18923197

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 03:40:12