发送标头后无法设置标头

时间:2018-11-21 09:48:37

标签: node.js

我创建了一个常见的错误处理中间件来处理应用程序中的所有错误。 但是当我运行api时会显示一些错误,例如“错误:发送标头后无法设置标头”。 我正在通过使用未定义的错误'a'(例如 res.json(“ testing” + a);

)来手动引发错误

错误:

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (D:\nodejs\synchronizer\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (D:\nodejs\synchronizer\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (D:\nodejs\synchronizer\node_modules\express\lib\response.js:267:15)
    at process.on (D:\nodejs\synchronizer\middlewares\logging.js:31:21)
    at emitTwo (events.js:131:20)
    at process.emit (events.js:214:7)
    at emitPendingUnhandledRejections (internal/process/promises.js:108:22)
    at runMicrotasksCallback (internal/process/next_tick.js:124:9)
[nodemon] app crashed - waiting for file changes before starting...

server.js

const express = require('express');
const log = require('../middlewares/logging');
module.exports = function(app){
    // default options
    app.use(fileUpload());

    //it is required for form submit for post method
    app.use(express.json());
    const bodyParser = require("body-parser");

    /** bodyParser.urlencoded(options)
     * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
     * and exposes the resulting object (containing the keys and values) on req.body
     */

    // for parsing application/json
    app.use(bodyParser.json()); 
    app.use(bodyParser.text());
    // for parsing application/xwww-
    app.use(bodyParser.urlencoded({ extended: true })); 
    //form-urlencoded

    // for parsing multipart/form-data
    //app.use(upload.array()); 

    //this is middleware is responsible to serve websites static contents of public folder
    app.use(express.static('public'));

    //Every Request Response Logging Middleware
    app.use(log);

    app.get('/test', async (req, res) => {
        res.json("testing"+a);
    });
}

logging.js

const winston = require('winston');

var getLabel = function (callingModule) {
  var parts = callingModule.filename.split('/');
  return parts[parts.length - 2] + '/' + parts.pop();
};

module.exports = function(req, res, next) {
  const logger = winston.createLogger({
    levels: winston.config.syslog.levels,
    transports: [
      new winston.transports.File({
        filename: 'Logs/combined.log',
        level: 'info'
      })
    ],
    exitOnError: false
  });

  var logmsg = {
    'Request IP':req.ip,
    'Method':req.method,
    'URL':req.originalUrl,
    'statusCode':res.statusCode,
    'headers':req.headers,
    'Time':new Date()
  };

  process.on('unhandledRejection', (reason, p) => {
    logger.error('exception:'+reason);
    //below line causes an error
    res.status(200).json({
        'statuscode': 200,
        'message': 'Validation Error',
        'responsedata': 'Unhandled Exception Occured'
    });  
  });
  logger.log('info', logmsg);
  next();
}

1 个答案:

答案 0 :(得分:1)

您正在为每个请求创建一个新的记录器,并为unhandledRejection添加一个新的处理程序。

相反,创建单个记录器和单个处理程序。例如:

const winston = require('winston');

// one (module-wide) logger
const logger = winston.createLogger({
  levels: winston.config.syslog.levels,
  transports: [
    new winston.transports.File({
      filename: 'Logs/combined.log',
      level: 'info'
    })
  ],
  exitOnError: false
});

// one (app-wide) handler
process.on('unhandledRejection', (reason, p) => {
  logger.error('exception:'+reason);
});

// the logging middleware
module.exports = function(req, res, next) {
  const logmsg = {
    'Request IP':req.ip,
    'Method':req.method,
    'URL':req.originalUrl,
    'statusCode':res.statusCode,
    'headers':req.headers,
    'Time':new Date()
  };
  logger.log('info', logmsg);
  next();
}

如果要处理在请求/响应周期中发生的错误,请添加a proper error handler