# Changes to error and exception handling

Many fatal and recoverable fatal errors have been converted to exceptions in PHP 7. These error exceptions inherit from the `Error` class, which itself implements the `Throwable` interface (the new base interface all exceptions inherit).

This means that custom error handlers may no longer be triggered because exceptions may be thrown instead (causing new fatal errors for uncaught `Error` exceptions).

A more complete description of how errors operate in PHP can be found [on the Throwable errors page](#language.error-handling.throwable). This migration guide will merely enumerate the changes that affect backward compatibility.

### `set_exception_handler` is no longer guaranteed to receive `Exception` objects

Code that implements an exception handler registered with `set_exception_handler` using a type declaration of `Exception` will cause a fatal error when an `Error` object is thrown.

If the handler needs to work on both PHP 5 and 7, you should remove the type declaration from the handler, while code that is being migrated to work on PHP 7 exclusively can simply replace the `Exception` type declaration with `Throwable` instead.

<div class="informalexample">

```
<?php
// PHP 5 era code that will break.
function handler(Exception $e) { /* ... */ }
set_exception_handler('handler');

// PHP 5 and 7 compatible.
function handler($e) { /* ... */ }

// PHP 7 only.
function handler(Throwable $e) { /* ... */ }
?>

   
```

</div>

### Internal constructors always throw exceptions on failure

Previously, some internal classes would return ENTITY or an unusable object when the constructor failed. All internal classes will now throw an `Exception` in this case in the same way that user classes already had to.

### Parse errors throw `ParseError`

Parser errors now throw a `ParseError` object. Error handling for `eval` should now include a ENTITY block that can handle this error.

### E_STRICT notices severity changes

All of the `E_STRICT` notices have been reclassified to other levels. `E_STRICT` constant is retained, so calls like `error_reporting(E_ALL|E_STRICT)` will not cause an error.

| Situation | New level/behaviour |
|----|----|
| Indexing by a resource | `E_NOTICE` |
| Abstract static methods | Notice removed, triggers no error |
| "Redefining" a constructor | Notice removed, triggers no error |
| Signature mismatch during inheritance | `E_WARNING` |
| Same (compatible) property in two used traits | Notice removed, triggers no error |
| Accessing static property non-statically | `E_NOTICE` |
| Only variables should be assigned by reference | `E_NOTICE` |
| Only variables should be passed by reference | `E_NOTICE` |
| Calling non-static methods statically | `E_DEPRECATED` |

`E_STRICT` notices severity changes