I have a 404.jade
file that I want to render whenever there is an invalid GET request.
Here is my current code:
app.js
import Koa from 'koa'
import views from 'koa-views'
import serve from 'koa-static'
import rootRoutes from './routes/index'
import userRoutes from './routes/user'
const app = new Koa()
app.use(views(`${__dirname}/views`, { extension: 'jade' }))
app.use(serve(`${__dirname}/public`))
app.use(rootRoutes.routes())
app.use(userRoutes.routes())
app.listen(3000, () => {
console.log('Server running at http://localhost:3000')
})
export default app
routes/index.js
import Router from 'koa-router'
const router = new Router()
router.get('/', async ctx => {
await ctx.render('index')
})
router.get('/about', async ctx => {
await ctx.render('about')
})
export default router
routes/user.js
import Router from 'koa-router'
const router = new Router({ prefix: '/user' })
router.get('/:name', async ctx => {
const user = ctx.params.name
await ctx.render('user', { user })
})
export default router
How can I handle any type of invalid GET request and somehow use await ctx.render('404')
whenever it happens?
You can add a custom middleware
in your app.js
file.
import Koa from 'koa'
import views from 'koa-views'
import serve from 'koa-static'
import rootRoutes from './routes/index'
import userRoutes from './routes/user'
const app = new Koa()
app.use(async(ctx, next) => {
try {
await next()
const status = ctx.status || 404
if (status === 404) {
ctx.throw(404)
}
} catch (err) {
ctx.status = err.status || 500
if (ctx.status === 404) {
//Your 404.jade
await ctx.render('404')
} else {
//other_error jade
await ctx.render('other_error')
}
}
})
app.use(views(`${__dirname}/views`, { extension: 'jade' }))
app.use(serve(`${__dirname}/public`))
app.use(rootRoutes.routes())
app.use(userRoutes.routes())
app.listen(3000, () => {
console.log('Server running at http://localhost:3000')
})
export default app
The default value of ctx.response.status is 404
application.js line 125 :
callback() {
const fn = compose(this.middleware);
if (!this.listeners('error').length) this.on('error', this.onerror);
const handleRequest = (req, res) => {
res.statusCode = 404; // defaul
const ctx = this.createContext(req, res);
const onerror = err => ctx.onerror(err);
const handleResponse = () => respond(ctx);
onFinished(res, onerror);
return fn(ctx).then(handleResponse).catch(onerror);
};
return handleRequest;
}
and if you call :
this.render('index',{});
this.send();
this.body='';
the status code will change automatically.
So we can just use this :
app.use(async (ctx, next) => {
if(parseInt(ctx.status) === 404){
ctx.status = 404
ctx.body = {msg:'emmmmmmm, seems 404'};
}
})
Warning here, if you are using koa-router
, make sure the function above is called with app.use
( app = new Koa() ), not router.use
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With