Express-winston middleware error on GET and POST request to mongoDB

Viewed 982

I have the following structure:

logger.js:

const logger = module.exports = require('winston')

logger.add(new logger.transports.File(
{
    name: 'debug-file',
    filename: 'log.log',
    level: 'debug',
    handleExceptions: true,
    humanReadableUnhandledException: true,
    exitOnError: true,
    json: false,
    maxsize: 104857600,
    maxfiles: 5
}))

logger.add(new logger.transports.Console(
{
    name: 'error-console',
    level: 'error',
    handleExceptions: true,
    humanReadableUnhandledException: true,
    exitOnError: true
}))

server.js:

const port = process.env.PORT || 5000;

const logger = require('./logger.js')
const database = require('./database/createDatabase.js')({ logger })
const app = require('./app/createExpressApp.js')
const server = require('http').createServer()

server
    .on('request', app)
    .on('listening', function() {
        const addr = this.address()
        const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`
        logger.info(`Listening on ${bind}`)
    })
    .on('error', function(error) {
        if (error.syscall !== 'listen') throw error
        const addr = this.address() || { port }
        const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`
        switch (error.code) {
            case 'EACCES':
                logger.error(`${bind} requires elevated privileges`)
                process.exit(1)
            case 'EADDRINUSE':
                logger.error(`${bind} is already in use`)
                process.exit(1)
            default:
                throw error
        }
    })
    .listen(port)

createDatabase.js:

const mongoose = require('mongoose')
const glob = require('glob')
const path = require('path')

module.exports = ({ logger }) => {

    const url = process.env.ATLAS_URI
            || "mongodb+srv://(removed for stackoverflow question)"

    mongoose.connect(url)

    const db = glob.sync('./schemas/**/*.js', { cwd: __dirname })
    .map(filename => {
        return {
            schema: require(filename),
            name: path
                .basename(filename)
                .replace(path.extname(filename), ''),
        }
    })
    .map(({name, schema}) => mongoose.model(name, schema))
    .reduce((db, model) => {
        return {
            ...db,
            [model.modelName]: model,
        }
    }, {})

    mongoose
    .connection
    .on('error', error => {
        throw error
    })
    .once('open', () => logger.info(`MongoDB connection established successfully!`) && 
        console.log(`MongoDB connection established successfully!`))

    return db
}

and finally getUsers.js:

const Router = require('express').Router

// export to router
module.exports = Router({mergeParams: true})
.get('/v1/users', async (req, res, next) => {
    try {
        const users = await req.db.User.find()
        res.send(users)
    }
    catch (error) {
        next(error)
    }
})

I have triple checked folder structure, syntax and everything else I can think of, but think I lack understanding of winston. I get the following error when I go to perform GET request for Users:

{"error":{},"level":"error","message":"uncaughtException: transports or a winstonInstance are required by express-winston middleware

I have a feeling its a rudimentary error and I'm missing something simple. Anyone have ideas on what would be causing the error?

1 Answers

This is because your logger, and database are not imported into your server.js

Change your server.js imports from

const port = process.env.PORT || 5000;

const logger = require('./logger.js')
const database = require('./database/createDatabase.js')({ logger })
const app = require('./app/createExpressApp.js')
const server = require('http').createServer()

to

const port = process.env.PORT || 5000;

const logger = require('./logger.js')
const database = require('./database/createDatabase.js')({ logger })
const app = require('./app/createExpressApp.js')({ logger, database });
const server = require('http').createServer()

both, database and the Winston logger are exported, however, they are not being pushed to the createExpressApp.js, which is needed and will remove this error and log the requests from postman/server properly in your log file.

This is an error from express-winston, which requires the winstonInstance to not be null. I bet if you try to console.log(logger) in your createExpressApp.js it will come back undefined.

Per the express-winston documentation: https://www.npmjs.com/package/express-winston

PS. Ensure you add:

mongoose.connect(url, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useFindAndModify: false,
    useUnifiedTopology: true,
  });

these methods to your mongoDB URL, or your will get depreciation warnings :D

Related