Hapi: reply.code(value) ignored when payload is empty and emptyStatusCode is set

Created on 17 May 2016  路  6Comments  路  Source: hapijs/hapi

Example:

const Hapi = require('hapi');

const server = new Hapi.Server();
server.connection({
    routes: {
        response: {
            emptyStatusCode: 204
        }
    }
});

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        reply().code(200);
    }
});

server.inject('/', (res) => {

    console.log(res.statusCode);   // 204
});

Not sure if this is intended behaviour but I expected to be able to set any status code I like in the handler, regardless of other route level settings. This feels like a bug because the code() value is honored if emptyStatusCode is not set, for example:

const Hapi = require('hapi');

const server = new Hapi.Server();
server.connection({
    // routes: {
    //     response: {
    //         emptyStatusCode: 204
    //     }
    // }
});

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        reply().code(400);
    }
});

server.inject('/', (res) => {

    console.log(res.statusCode);   // 400
});
bug

Most helpful comment

I would also expect code() to trump emptyStatusCode. I think the docs imply that it should work by saying that emptyStatusCode is "the _default_ HTTP status code when the payload is empty".

All 6 comments

I would also expect code() to trump emptyStatusCode. I think the docs imply that it should work by saying that emptyStatusCode is "the _default_ HTTP status code when the payload is empty".

It probably makes better sense to just set a route level emptyStatusCode for the route that you want the different statusCode on.

Nah, code() should work.

The problem is that the 204 feature is an override. The right way to do this is to set the 204 early instead of the 200 default. But that's not always possible because if it's a steam etc. we won't know the length until we marshal the payload and that only happens at the very end.

I can keep a flag to tell if the code was set manually or not, but that means all the internal code will still expect to see a 200 status code all the way until transmission.

I need to find a middle ground.

Just to confirm my understanding:

  1. if emptyStatusCode is default(i.e 200), then one can send any valid code from the handler using reply().code(x);
  2. if emptyStatusCode is set to 204 in routes, then one can send any valid code from handler except 200.
    So 204 feature is override only if reply.code(200), which probably is correct. Am I assuming anything wrong?

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mahnunchik picture mahnunchik  路  4Comments

arb picture arb  路  4Comments

foobar1123 picture foobar1123  路  3Comments

jeremiahlee picture jeremiahlee  路  4Comments

jney picture jney  路  4Comments