Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A catch-all 404 handler for koa? #158

Open
slavafomin opened this issue Aug 5, 2022 · 4 comments
Open

A catch-all 404 handler for koa? #158

slavafomin opened this issue Aug 5, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@slavafomin
Copy link

slavafomin commented Aug 5, 2022

Hello!

I'm trying to implement a pretty trivial thing — a catch-all handler that will return 404 when request handler is not found for the request in question, however, I can't find any related examples in the docs and the Internet. What is the best practice for this?

The example below won't work because the router.all('/(.*)') will intercept all requests after they were handled. Of course I can do something like context.handled = true and then check for this flag in the catch-all handler, but this will be a boilerplate code that should actually be handled by the router itself. Avoiding a call to next() in the request handler will also be a mistake, because it will break the middleware that do request post-processing (e.g. response transformation, etc). If I change the order of handler registration then I will need to set proper status in all the request handlers.

router.get('/health', (context, next) => {
  context.body = {
    status: 'ok',
  };
  return next();
});

router.all('/(.*)', (context, next) => {
  context.status = 404;
  context.body = {
    message: 'Not found',
  };
  return next();
});

I believe the router should provide a special method for handling unhandled requests.

@slavafomin slavafomin added the enhancement New feature or request label Aug 5, 2022
@slavafomin slavafomin changed the title A catch-all 404 handler? A catch-all 404 handler for koa? Aug 6, 2022
@slavafomin slavafomin reopened this Aug 6, 2022
@ThaDaVos
Copy link

Sadly running into the same issue - did you find a solution?

@breavyn
Copy link

breavyn commented Sep 1, 2022

I handle this in the applications error middleware.

import * as createError from "http-errors";

const errorMiddleware = async (ctx, next) => {
  try {
    await next();

    if (ctx.status === 404) {
      throw createError(404);
    }
  } catch (err) {
    // handle error
  }
};

If any of my handled routes need to return 404, they do so by throwing an error. If await next(); completes without error, and the status is set to 404, I can assume the router has done this.

@zacanger
Copy link
Contributor

No need for the extra http-errors package, and also no need to even check the status, not really — the default is 404, so if you add a 404 handler after everything else (except for the listen or callback or whatever), you're all set:

app.use(async (ctx, next) => {
  ctx.status = 404
  ctx.body = 'Not found'
})

@fewbadboy
Copy link

yesterday, i also meet same problem too! the key is use wrong way of the next().this is my code example.

router/index.js

const router = new Router({
  prefix: '/api/v1'
})

router.get('/', (ctx, next) => {
  ctx.user = 'Hello'
  next()
}, (ctx, next) => {
  ctx.body = ctx.user
})

router.use(errorRouter.routes(), errorRouter.allowedMethods())

router.all(':pattern(.*)*',(ctx, next) => {
  console.log(ctx.params.pattern)
  ctx.redirect('/api/v1/error/404')
  ctx.status = 301
})

export default router

router/error/index,js

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

router
  .all('/404',(ctx, next) => {
    ctx.status = 404
    ctx.body = '404 Error Page'
  })

export default router

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants