Error and Exception
Error
Error Type
- Error.
- EvalError.
- RangeError.
- ReferenceError.
- SyntaxError.
- TypeError.
- URIError.
- AggregateError.
- 自定义错误.
class Error {
// Instance properties
message: string
cause?: any // ES2022
stack: string // non-standard but widely supported
constructor(message = '', options?: ErrorOptions) {
this.name = 'Error'
this.message = message
this.cause = options?.cause // ES2022: error chain.
}
}
interface ErrorOptions {
cause?: string | Error // ES2022
}
class CustomError extends Error {
constructor(message, options) {
super(message, options)
this.name = 'CustomError'
}
}
Error Object
const err = {
name: 'XXError',
message: 'something wrong',
extra: 'This was rather embarrassing',
remedy: genericErrorHandler, // 处理错误的函数名.
}
try {
throwError()
} catch (e) {
console.log(e.message)
e.remedy() // genericErrorHandler.
}
Exception
Call Stack Overflow
调用栈尺寸限制异常, 应立即定位在代码中的递归实例上:
try {
recursion()
} catch (ex) {
console.error('error info')
}
Exception Handling
try catch.Promise.catch.window.addEventListener('error', handler, true).window.addEventListener('unhandledrejection', handler, true).- Web Worker heartbeat monitoring.
process.on('uncaughtException', handleError).process.on('SIGHUP', handleExit).process.on('SIGINT', handleExit).process.on('SIGQUIT', handleExit).process.on('SIGTERM', handleExit).- AOP (Aspect Oriented Programming): Middleware/Interceptor/Monkey Patch.
- 在可能失败的地方抛出异常, 对失败处做标签, 易于调试与测试.
- 修复 bug 后, 可考虑是否在此处抛出异常.
- Avoid using try-catch inside a loop:
const object = ['foo', 'bar']
try {
for (let i = 0; i < object.length; i++) {
// do something that throws an exception
}
} catch (e) {
// handle exception
}
// 监听捕获阶段的异常事件
window.addEventListener(
'error',
(error) => {
handleError(error)
error.preventDefault()
},
true
)
// Un-catch `Promise` handler
window.addEventListener(
'unhandledrejection',
(error) => {
handleError(error)
error.preventDefault()
},
true
)
const instance = axios.create({
baseURL: 'https://api.test.com',
timeout: 15000,
headers: {
'Content-Type': 'application/json',
},
})
instance.interceptors.response.use(
(response) => {
return response.data
},
(error) => {
// 发生异常会走到这里
if (error.response) {
const response = error.response
if (response.status >= 400)
handleError(response)
} else {
handleError(null)
}
return Promise.reject(error)
}
)
globalThis.onunhandledrejection = (event) => {
console.log(event.type)
// "unhandledrejection"
console.log(event.reason.message)
// "Oops!"
console.log(rejected === event.promise)
// true
}
globalThis.onrejectionhandled = (event) => {
console.log(event.type)
// "rejectionhandled"
console.log(event.reason.message)
// "Oops!"
console.log(rejected === event.promise)
// true
}
const possiblyUnhandledRejections = new Map()
// when a rejection is unhandled, add it to the map
globalThis.onunhandledrejection = (event) => {
// prevents the console warning
event.preventDefault()
possiblyUnhandledRejections.set(event.promise, event.reason)
}
// when a rejection is handled, remove it from the map
globalThis.onrejectionhandled = (event) => {
possiblyUnhandledRejections.delete(event.promise)
}
setInterval(() => {
possiblyUnhandledRejections.forEach((reason, promise) => {
console.error('Unhandled rejection')
console.error(promise)
console.error(reason.message ? reason.message : reason)
// do something to handle these rejections
})
possiblyUnhandledRejections.clear()
}, 60000)
const rejected = Promise.reject(new Error('Oops!'))
process.on('unhandledRejection', (reason, promise) => {
console.log(reason.message)
// "Oops!"
console.log(rejected === promise)
// true
})
const rejected = Promise.reject(new Error('Oops!'))
setTimeout(() => {
// "rejectionhandled" triggered here
rejected.catch(
reason => console.error(reason.message) // "Oops!"
)
}, 500)
process.on('rejectionHandled', (promise) => {
console.log(rejected === promise) // true
})
const possiblyUnhandledRejections = new Map()
// when a rejection is unhandled, add it to the map
process.on('unhandledRejection', (reason, promise) => {
possiblyUnhandledRejections.set(promise, reason)
})
process.on('rejectionHandled', (promise) => {
possiblyUnhandledRejections.delete(promise)
})
setInterval(() => {
possiblyUnhandledRejections.forEach((reason, promise) => {
console.error('Unhandled rejection')
console.error(promise)
console.error(reason.message ? reason.message : reason)
// do something to handle these rejections
})
possiblyUnhandledRejections.clear()
}, 60000)