Search code examples
node.jsasync-awaithttp-status-code-404koa

Await on findOne returns not found (404) all the time


the below code returns not found (404) all the time. But the console logs the data as expected. I am using Node, Koa, and Mongoose.

the server.js

const Koa = require('koa');
const bodyparser = require('koa-bodyparser');
const UserRoutes = require('./router/user.routes');
const TrustRoutes = require('./router/trust.routes');
const auth = require('./middleware/auth');
const app = new Koa();

require('dotenv').config();
require('./db');

app.use(bodyparser());

app.use(auth);

app.use(
   TrustRoutes.routes()
).use(TrustRoutes.allowedMethods());

app.use(
   UserRoutes.routes()
).use(UserRoutes.allowedMethods());

app.listen(process.env.PORT || 3000);

trust.routes.js

const router = new Router({
    prefix: '/trust'
});


router.get('/:trustId', async (ctx,next) => {
    let id = ctx.params.trustId;
    let trust = await Trust.findById(id);
    console.log(trust);
    ctx.response.body = {
        status: true,
        message: 'Trust info',
        data: trust
    };
    console.log('trust info');
    next();
});

module.exports = router

the console logs the below details

{
  _id: new ObjectId("61ed34100ebd7c8fbdbef596"),
  name: 'new trust',
  description: 'match',
  contact: { email: '[email protected]', phone: '90334' },
  isActive: true,
  createdAt: 2022-01-23T10:55:12.866Z,
  updatedAt: 2022-01-23T10:55:12.866Z,
  __v: 0
}
trust info

and the middleware (I suspect in here)

require('dotenv').config();
const jwt = require("jsonwebtoken");
const User = require("../models/user")

const except = [
    '/user/login'
];

const verifyToken = async (ctx, next) => {

if (except.indexOf(ctx.request.path) >= 0) return next();

let  token = (
    ctx.request.body.token || ctx.request.query.token ||
    ctx.request.headers["authorization"]
);

if (!token) {
    ctx.response.status = 403;
    ctx.body = {
        status: false,
        message: 'Unauthorized'
    }
    return;
}
token = token.replace(/^Bearer\s+/,'');
try {
    const decoded = jwt.verify(token, process.env.TOKEN_KEY);
    const user = await User.findOne({
        email: decoded.username
    },{password: 0});
    ctx.request.user = user;
} catch (err) {
    ctx.response.status = 403;
    ctx.body = {
        status: false,
        message: 'Unauthorized'
    }
    return;
}
next();
};
module.exports = verifyToken;

I know that something in here is not correct but hard to understand since it's my first time on these async and koa with middleware please help me out on this.

the postman enter image description here


Solution

  • You don't export anything from your router-file. In order to use

    app
    .use(TrustRoutes.routes())
    .use(TrustRoutes.allowedMethods());
    

    you need to export the koa-router from the TrustRoutes-file:

    const router = new Router({
        prefix: '/trust'
    });
    
    router.get('/:trustId', async (ctx,next) => {
        // ...
    });
    
    module.exports = router;
    

    Apart from this when using async handlers, you need to either return next or await (see https://github.com/ZijianHe/koa-router/issues/476):

    router.get('/:trustId', async (ctx,next) => {
            // ...
        return next(); // or await next();
    });