21

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

34

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.
}
| improve this answer | |
  • What function does this code go in, within template.php? – Jordan Magnuson Nov 20 '12 at 8:13
  • 1
    You can place this code inside template_preprocess_page(&$variables) – fzmaster Nov 26 '12 at 14:46
  • This can also be implemented in hook_exit() – sheldonkreger Nov 26 '14 at 22:03
  • If you're looking to handle a 403, you can use: if ($status == '403 Forbidden') { /* ... do stuff ... */ } – tyler.frankenstein Mar 27 '15 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. – JamesWilson Mar 8 '18 at 17:40
12

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

| improve this answer | |
  • 1
    This is just what I was looking for! <3 – JamesWilson Mar 8 '18 at 17:37
  • 1
    Careful though - the object retruned there might not have a getStatusCode function. – fritzmg Mar 22 '18 at 17:45
  • It ends my endless search and trying. – usmanjutt84 Jul 23 '19 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']);
| improve this answer | |
  • $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 '14 at 1:18
  • menu_get_item, bit expensive call per page no? – Kevin Sep 9 '15 at 19:47

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