【娱乐向】JavaScript 异常处理的正确打开方式

废话不多说,先来看一段代码

function funnyCatchError(cb: () => any) {
    try {
        cb()
    } catch (error) {
        window.open(`https://www.baidu.com/s?wd=${error.message}`)
    }
}

想必稍有点 JavaScript 知识的人都知道这段代码在干什么,就是在 cb() 函数出错的时候把页面自动跳转到百度……

这段代码是以前不知道在什么地方看到的,具体的我也忘了,大概就是这么个逻辑,下面我们来优化一下(一本正经)。

新增对异步函数的支持

上面这段代码仅只是同步函数,对于异步函数的支持并不友好,下面我们来优化一下,让它支持 async/await。

对于异步函数的支持,只需要在执行函数前使用 await 即可,如果是同步函数则会直接返回结果。

同时 await 只能用在异步函数内,所以修改为异步函数

async function funnyCatchError(cb: () => any) {
    try {
        await cb()
    } catch (error) {
        window.open(`https://www.baidu.com/s?wd=${error.message}`)
    }
}

显然,这段代码并没有对环境进行判断,由于这种骚操作只能在浏览器端使用,因此最好先判断是否为浏览器环境。

虽然 Node.js 端也可以采用自动打开浏览器的方式,但考虑到后端都是跑在 Linux 服务器上的,都不一定有浏览器,所以还是算了吧

判断是否为浏览器

只要判断有没有 window 对象就完事了。

async function funnyCatchError(cb: () => any) {
    try {
        await cb()
    } catch (error) {
        if (!window){
            throw error
        }
    }
}

下面来判断 error 的数据类型。

判断 error 的数据类型

考虑到并不是所有人抛异常的时候都是乖乖的抛个 Error 对象出来,因此我们这里还要做一层判断,同时加入对 string 的支持。

async function funnyCatchError(cb: () => any) {
    try {
        await cb()
    } catch (error) {
        if (!window){
            throw error
        }
        let errorMessage: string
        if (error instanceof Error){
            errorMessage = error.message
        } else if (typeof error === 'string'){
            errorMessage = error
        }
    }
}

最后就可以跳转搜索引擎了

async function funnyCatchError(cb: () => any) {
    try {
        await cb()
    } catch (error) {
        if (!window){
            throw error
        }
        let errorMessage: string
        if (error instanceof Error){
            errorMessage = error.message
        } else if (typeof error === 'string'){
            errorMessage = error
        }
        if (errorMessage){
            console.error(error)
            window.open(`https://www.baidu.com/s?wd=${errorMessage}`)
            //直接弹窗是有可能被浏览器拦截的,因此也可以采用以下的方式
            // window.location.href = `https://www.baidu.com/s?wd=NULL` 
        }
    }
}

其他情况的冗余兜底

如果 errorMessage 为空就把异常向上抛出

async function funnyCatchError(cb: () => any) {
    try {
        await cb()
    } catch (error) {
        if (!window){
            throw error
        }
        let errorMessage: string
        if (error instanceof Error){
            errorMessage = error.message
        } else if (typeof error === 'string'){
            errorMessage = error
        }
        if (errorMessage){
            console.error(error)
            window.open(`https://www.baidu.com/s?wd=${errorMessage}`)
            return
        }
        throw error
    }
}

结尾

这次实现了一个娱乐向的异常处理函数,具体的代码放在了 GitHub 上,感兴趣的小伙伴可以看一下。

顺便在此郑重提醒:本函数纯属娱乐,生产环境请勿使用,否则后果自负

GitHub 地址:https://github.com/CaoMeiYouRen/funny-catch-error


评论

发表回复