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
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.
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 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.
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.
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.