[Coldbox 7] Optimal Way to Get Current HTTP Status Code?

In Coldbox 7, what is the optimal way to get the current HTTP status code from within a layout?

I know handlers can set HTTP status codes like this:

event.setHTTPHeader( "400", "Bad Request" ); 

However, once it’s set, how can you get it?

Calling event.getHttpHeader( "statusCode" ) only returns an empty string.

If it doesn’t already exist, I feel like there should be a convenience method within event called getHttpStatusCode() which could tap into the pageContext() to get the currently set statusCode

Update:

The currentRouteRecord contains a key for statusCode which can be used. However, keep in mind that you can only get the currentRouteRecord data if the route is explicitly set in the Router.cfc file. If you’re working with the default route (e.g. main.index), currentRouteRecord will be an empty struct.

So you could probably do something like this:

currentRouteRecord = event.getCurrentRouteRecord();
statusCode = currentRouteRecord.isEmpty() ? 200 : currentRouteRecord.statusCode;

Does this give you what you want?
getPageContextResponse().getStatus() returns a numeric.

Thanks for the reply @aliaspooryorik, but getPageContextResponse() is a private method within Coldbox’s Botstrap.cfc. So it can’t be called directly.

Regardless, I tried manually getting the response, by doing exactly what getPageContextResponse() does by executing:

getPageContext().getResponse().getResponse().getStatus(); // ACF

ACF returns a value of 0.
Lucee returns the expected value of 200.

Try comparing the above and you will see ACF returns 0.

I was hoping to dig into Coldbox’s storage of where the status code header lives. There’s a public setter, but no getter unfortunately.

With ACF you have to call getPageContext().getResponse().getResponse() to get the actual response object

@jclausen I believe that was fixed in ACF 2018+

Calling either of these will give the same result in ACF 2018, 2021, or 2023

writeDump( getPageContext().getResponse().getStatus() );
writeDump( getPageContext().getResponse().getResponse().getStatus() );

I’m not sure why it returns 0 though instead of the actual HTTP status code.

That’s note entirely true. It’s worth noting that the servlet spec doesn’t not have any method called getResponse() on the HttpServletResponse class, that’s just a common pattern people use when they wrap the original response in a class of their own. Adobe actually sometimes wraps the servlet’s response object several times, and fusionreactor will also wrap it, if installed on the server.

That said, the outermost response object SHOULD delegate the getStatus() method to the wrapped response(s) so I don’t think there’s any need to try to dig down and finding the original servlet response.

Prolly because we’re making vast assumptions about how CF works :slight_smile: CF is under no obligation to write the response code out to the servlet just because we called a CF tag or BIF to set it. Doing this often times commits the response and begins flushing it to the browser right then, making it impossible to redirect, add headers/cookies, set content type, etc. So CF likely stores the status code it plans to set internally and waits to actually hand it to the underlying servlet until the request is finished. CF, as a language, provides no documented arrangement for looking at a status code that you’ve previously set, and since CF is providing an abstraction on top of the servlet classes, we can’t guarantee how it will necessarily interact with them.

Thanks @bdw429s. Yeah, I was afraid of that.

Here’s a possible workaround to get the intended HTTP status code:

Pull it from event.getCurrentRouteRecord();
If the route is explicitly defined in your Router.cfc, the HTTP response status code resides in a key called statusCode. The below code assumes the status code is 200 unless otherwise specified.

currentRouteRecord = event.getCurrentRouteRecord();
statusCode = currentRouteRecord.isEmpty() ? 200 : currentRouteRecord.statusCode;

So, if you ever manually set the status code using code like: event.setHTTPHeader( "404", "Not Found" ), you should be able to retrieve it using the workaround I supplied above.

Yep, ColdBox has its own layer of abstraction (and status code storage) just like CF has its layer of abstraction (and status code storage) on top of the servlet. If all your status codes are set via ColdBox, then that may work ok for you.

Ah yeah sorry - it’s exposed in the RestHandler (via prc.response), but doesn’t seem to be in a ‘standard’ handler.