25

How to check, in D7, if the current page is returning a 404 error from a module/template?

2

3 Answers 3

37

In Drupal 7, you can use drupal_get_http_header().

In the template.php file, use this code.

$status = drupal_get_http_header("status");
if ($status === '404 Not Found'){
  // Do something.
}

In Drupal 8, you can use the following code in a hook.

$route_name = \Drupal::request()->attributes->get('_route');
if ('system.404' === $route_name) {
  // Do something.
}
6
  • What function does this code go in, within template.php? Nov 20, 2012 at 8:13
  • 1
    You can place this code inside template_preprocess_page(&$variables)
    – fzmaster
    Nov 26, 2012 at 14:46
  • This can also be implemented in hook_exit() Nov 26, 2014 at 22:03
  • If you're looking to handle a 403, you can use: if ($status == '403 Forbidden') { /* ... do stuff ... */ } Mar 27, 2015 at 22:59
  • 2
    Note: the solution for Drupal 8 based on the system.404 route does not work if you've specified a node page as your 404 page in Configuration > System > Basic site settings . See @Gervase' answer for a solution that works when you either have or do not have a custom 404 page specified. Mar 8, 2018 at 17:40
16

Drupal 8.2.x:

Unfortunately, drupal_get_http_header("status") doesn't work any more.

Try:

$status = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception');
if ($status && $status->getStatusCode() == 404){

}

There is a discussion of this here: https://www.drupal.org/node/1969270

3
  • 1
    This is just what I was looking for! <3 Mar 8, 2018 at 17:37
  • 1
    Careful though - the object retruned there might not have a getStatusCode function.
    – fritzmg
    Mar 22, 2018 at 17:45
  • It ends my endless search and trying. Jul 23, 2019 at 7:30
4

This is the simplest way to detect Access Denied (403) and Page Not Found (404) in Drupal 7.

// get the menu router item for the current page
$router_item = menu_get_item();

// if there is no router item, this page is not found
$is_page_not_found_404 = empty($router_item);

// if 'access' is empty for the router item, access is denied
$is_access_denied_403 = empty($router_item['access']);
2
  • $router_item won't be empty if the site_404 variable is set to a node path, so additional checks would be needed.
    – gapple
    Dec 10, 2014 at 1:18
  • menu_get_item, bit expensive call per page no?
    – Kevin
    Sep 9, 2015 at 19:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.