Error handling in the Node project
The use of Error objects in node
Add the built-in error message using the captureStackTrace method
CaptureStackTrace var obj = {message:'something is wrong'} Error. CaptureStackTrace (obj) throw obj // The message inside the obj object is thrownCopy the code
Use try catch to catch errors
Error messages can be caught by simply writing code in a try catch
try{
throw new Error('oh no')
}catch(e){
console.log(e)
}
Copy the code
In asynchronous code, a direct try catch does not catch the error message, so you can use the following method
function foo(params, cb){
const error = new Error('something is wrong')
if(error) cb(error)
}
Copy the code
Node already supports async await, so use callback to handle errors
async function foo(){
try{
await bar()
}catch(e){
console.log(e)
}
}
async function bar(){
throw new Error('async function got wrong) } foo()Copy the code
Basic error types
Error messages can be handled in multiple places in a project, so write a basic error type first for ease of use
// Class HttpBaseError extends Error {constructor(httpStatusCode, httpMsg, errCode, MSG) {super(' HTTP Error:${msg}`); this.httpStatusCode = httpStatusCode; this.httpMsg = httpMsg; this.errCode = errCode; }} try {// throw new HttpBaseError(404,'Resource does not exist', 10000, 'resouse is not found');
} catch (e) {
console.log(e.message);
console.log(e.httpStatusCode);
console.log(e.httpMsg);
console.log(e.errCode);
}
Copy the code
Specific error type
In addition to the basic type, different cases have different error messages, and you need to use a specific error type to handle a specific error message
Const ERROR_CODE = 40000 class HttpRequestParamError extends HttpBaseError {constructor(paramName,) desc, msg) { super(200, desc, ERROR_CODE, `${paramName} wrong: ${msg}`)}}Copy the code
This makes it very easy to call the error type to return an error if the argument is wrong
Throw the logic wrong
In error handling, some errors in model and controller cannot be returned directly to the user, but should only be returned to the caller of model or Controller.
Use error handling
Controller/model errors are handled using specified error types, such as HttpRequestParamError. At the end of all routes, an error handler is required to handle all errors in a centralized manner
// error handler
function handler(options) {
return function (err, req, res, next) {
if(err instanceof HttpRequestParamError) {// Here we do different things for different errors console.log('http request error')
res.statusCode = err.httpStatusCode
res.json({
code: err.errCode,
msg: err.httpMsg
})
} elseNext (err)}}Copy the code
In addition to predictable errors, there are also unknown types of errors, in which case an unknown error handler is required to handle the rest of the errors
function unKnowErrorHandler(options) {
return function (err, req, res, next) {
console.log(err)
res.json({
code: 99999,
msg: 'unKnow error'}}})Copy the code
Logs in node
Normally, there is no problem with using console to debug, but in online environment, we cannot see console effectively. Using log system can better facilitate online debugging and recording information
The use of Winston
Winston is a logging plug-in commonly used in Node
const winston = require('winston')
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({
name: 'info_logger', / /logThe name of the filename:'logs/info.log'// Log file address level:'info'/ / setlog}), // The second logger, which records the error levellog
new winston.transports.File({
name: 'error_logger',
filename: 'logs/error.log',
level: 'error']}})); // The error level is higher than info. The error. Log file only records the error log logger.error('first error log with winston'// the info level will be recorded in the filelogAnd higher than infologFor example error logger.info('first info log with winston')
Copy the code
Log rotation
In applications that generate a large amount of data, the output of logs is large. Therefore, logs need to be split, for example, logs are recorded according to the frequency of each day.
Winston doesn’t have its own log rotation, so we need to introduce the Winston-daily-rotate-file library
const {
createLogger,
format,
transports
} = require('winston');
const {
combine,
timestamp,
label,
prettyPrint
} = format;
require('winston-daily-rotate-file')
var transport = new(transports.DailyRotateFile)({
filename: './logs/app-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
maxSize: '20m',
maxFiles: '14d',
format: combine(
label({
label: 'right meow! '
}),
timestamp(),
prettyPrint()
),
});
transport.on('rotate'.function (oldFilename, newFilename) {});
var logger = createLogger({
transports: [
transport
]
});
logger.info('Hello World! ');
Copy the code
Run the log file, at which point today’s log is generated in the logs directory
Welcome to my blog