Backend Development

PHP 7 Catching Errors Using Throwable and Exception

PHP 7 Catching Errors Using Throwable and Exception

Ideally in any programming language to catch errors you must wrap your code in a try-catch block or depending in the language you can report the errors with other mechanisms.

 

 

However in PHP as we know there are two types of errors, the traditional errors which are instances of the Error class. To report these errors we have to write a custom error handler or by checking for errors directly. Examples of these errors ArithmeticError, ParseError, TypeError, etc.

The other types of errors is the exceptions which extends the Exception class and can be easily caught using try-catch blocks.

In PHP 5 code the try-catch blocks only works with exceptions but trying to catch any other error related to the base Error class requires that we define a custom error handler using php set_error_handler() function.

For example:

// php 5 code
function sum($a, $b) 
{
   return $a + $b;
}


try
{
   $result = sum("a", "b");
   echo $result;
} catch (Exception $e) {
   
  echo "Error: " . $e->getMessage();
}

This code not caught in the try block and will show a TypeError:

PHP Fatal error:  Uncaught TypeError: Unsupported operand types: string + string

With the release of PHP 7 to generalize the error reporting so we can catch all types of errors using both Error and Exception most errors are now reported by throwing Error exceptions.

With this in mind we can catch specific errors like so:

try {
    // Throws an Error object in PHP 7.
} catch (Error $e) {
    // Handle error
}
try {
    require 'file-with-parse-error.php';
} catch (ParseError $e) {
    echo $e->getMessage(), "\n";
}
try {
   // Code that may throw an Exception or ArithmeticError.
} catch (ArithmeticError | Exception $e) {
   // show error message
}

In addition to that a new interface introduced, the Throwable interface. Throwable is the base interface for any object that can be thrown via a throw statement, including Error and Exception. 

So now we can catch all types of errors using Throwable. By modifying the previous example to use throwable:

try { 

   $result = sum("a", "b"); 
   echo $result; 
} catch (\Throwable $e) { 

   echo "Error: " . $e->getMessage();
} catch (\Exception $e) { 

   echo "Error: " . $e->getMessage();
}

Output:

Error: Unsupported operand types: string + string

php 7 throwable

 

 

 

 

 

 

 

 

 

As you Throwable at the top of the exception class hierarchy and all exception types now implement Throwable.

Throwable Terminology

 interface Throwable {
      /* Methods */
      public getMessage(): string
      public getCode(): int
      public getFile(): string
      public getLine(): int
      public getTrace(): array
      public getTraceAsString(): string
      public getPrevious(): ?Throwable
      abstract public __toString(): string
}

As you see the Throwable interface structure is the same as the Exception class but the difference is that Throwable::getPrevious() can return any instance of Throwable instead of Exception

 

We mentioned above that Throwable is an interface however you can’t implement it directly, and doing so will result in this error:

PHP Fatal error:  Class myCustomException cannot implement interface Throwable, extend Exception or Error instead

As the error say to implement Throwable you have to create another interface which implement Throwable and then create another class which extend Exception and implement the custom interface like so:

interface MyCustomThrowable extends \Throwable 
{

}

class MyCustomException extends \Exception implements MyCustomThrowable
{
   
}

We can use this class to catch all types of errors:

try { 

   throw new MyCustomException("System error");

} catch (MyCustomException $e) { 

   echo $e->getMessage();
} 

 

4.5 2 votes
Article Rating

What's your reaction?

Excited
2
Happy
2
Not Sure
0
Confused
1

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments