js异常处理

223 阅读1分钟

在JavaScript中,我们需要对程序运行时的错误进行捕获和处理,确保程序不会因为未处理的错误而中断。同时,我们还需要根据同步或者异步以不同的方式处理异常。

同步异常

同步异常处理是通过try...catch语句完成的,如:

function sum(a, b) {
    if (!+a || !+b) {
        throw Error('args must be a numeric value');
    }
    
    return a + b;
}

try {
    sum(1, 'A');
} catch (err) {
    console.error(`Caught error: ${err.message}`);
}

异步异常

异步异常处理,则需要以不同的方式处理

Promise异常

使用Promise对象自身的.catch方法来捕获异常,如:

fetch('https://')
    .catch((err) => console.error(`Caught error: ${err.message}`))

函数中异步调用异常

结合使用async/awaittry...catch来捕获异常,如:

async function loadData() {
    try {
        const data = await fetch('https://')
            .then((response) => response.data());
        
        console.log(data);
    } catch (err) {
        console.error(`Caught error: ${err.message}`)
    }
}

总结

  • 使用try...catch捕获同步异常
  • 使用.catch捕获Promise异常
  • 自定义错误类型,提供更清晰的错误上下文,便于在try...catch语句中对错误进行统一处理

下面是在实际开发中进行异常处理的例子:

// 自定义错误类型
class InvalidArgsError extends Error {
    constructor(message, code = 100) {
      super(message);

      this.name = 'InvalidArgsError';
      this.code = code;
  }
}

class InternalError extends Error {
    constructor(message) {
      super(message);

      this.name = 'InternalError';
    }
}

async function readUserInfoFromDB(userId) {
    return {
      id: userId,
      name: 'aric',
    }
}

async function readUserInfoFromCache(userId) {
    return null;
}

async function writeUserInfoToCache(userId, userInfo, expireTime) {
    return true;
}

// 处理请求函数
async function getUserInfo(ctx, next) {
    try {
        const { userId } = ctx.request.query;
    
        if (!userId || typeof userId !== 'string') {
          throw new InvalidArgsError('"userId" must to be a non-empty string');
        }
  
        let userInfo = await readUserInfoFromCache(userId);
        if (userInfo) {
          return userInfo;
        }
  
        userInfo = await readUserInfoFromDB(userId);
  
        // 采用异步调用形式,这样不会阻塞函数
        writeUserInfoToCache(userId, userInfo, 5 * 60)
            .catch((err) => console.error(`Write cache error: ${err.message}`));
            
        ctx.body = {
            userInfo,
        };
    } catch(err) {
        console.error(`Caught error: ${err.message}`);

        // 根据不同的错误类型进行特殊处理
        if (err instanceof InvalidArgsError) {
            ctx.status = 400;
            ctx.body = {
                message: err.message,
                code: err.code,
            };
        } else {
            ctx.status = 500;
            ctx.body = {
                message: 'Server is busy, please try again later',
            };
        }
    }
}