35
try     
{
    $matrix = Query::take("SELECT moo"); //this makes 0 sense

    while($row = mysqli_fetch_array($matrix, MYSQL_BOTH)) //and thus this line should be an error
    {

    }

    return 'something';
}
catch(Exception $e)
{
    return 'nothing';   
}

However instead of just going to catch part and returning nothing it shows a warning Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, null given in the line starting with while. I have never came up to using exceptions in php, but used them a lot in C# and it seems in PHP they are working differently or, as always, I am missing something obvious.

Andrius Naruševičius
  • 8,348
  • 7
  • 49
  • 78

5 Answers5

42

You can't handle Warnings/Errors with try-catch blocks, because they aren't exceptions. If you want to handle warnings/errors, you have to register your own error handler with set_error_handler.

But it's better to fix this issue, because you could prevent it.

Jeff
  • 13,943
  • 11
  • 55
  • 103
Philipp
  • 15,377
  • 4
  • 35
  • 52
  • building on this answer, you could easily set set_error_handler to capture PHP errors and issue an Exception, at which point your try-catch will work. I am sure you can Google for something suitable. – Mike Brant Sep 11 '12 at 20:58
  • For throwing exceptions, set_error_handler should be used in combination with ErrorException (built-in class specifically for this use). – oxygen Feb 28 '13 at 12:06
  • 1
    I've been doing php full time for a few years now, and I didn't even know this. – Captain Hypertext Jul 05 '16 at 18:01
  • You can *not* prevent users from using incorrect authentication credentials via `imap_open` so no, you can't prevent it. – John Nov 15 '21 at 04:19
39

Exception is only subclass of Throwable. To catch error you can try to do one of the following:

try {

    catch (\Exception $e) {
       //do something when exception is thrown
}
catch (\Error $e) {
  //do something when error is thrown
}

OR more inclusive solution

try {

catch (\Exception $e) {
   //do something when exception is thrown
}
catch (\Throwable $e) {
  //do something when Throwable is thrown
}

BTW : Java has similar behaviour.

Gilad Tiram
  • 499
  • 4
  • 3
  • 4
    I used `\Exception` instead of `Exception` and it worked. Can you elaborate on how a \ (slash) before `Exception` makes a huge difference here? – Shashanth Feb 19 '20 at 08:28
  • 5
    @Shashanth using `Exception` without a slash assumes you've got a `use Exception;` statement at the top, or aren't using namespacing, the `\ ` makes it look in the global PHP namespace, so it'll catch a PHP `Exception` and any classes based on it - official documentation: https://php.net/manual/en/class.exception.php – Sandra Jul 07 '20 at 17:33
  • In modern PHP, with the use of namespaces, the inclusion of the ' \ ' is essential. – James John McGuire 'Jahmic' May 19 '21 at 07:26
  • Genius, you saved my day! – w461 Oct 21 '21 at 08:43
  • This should be the accepted answer. Unlike some other languages, PHP has different sets of errors to handle. Fatal errors won't be handled if you only catch the Exception class. – Puspam Jul 07 '23 at 04:08
6

In PHP a warning is not an exception. Generally the best practice would be to use defensive coding to make sure the result is what you expect it to be.

datasage
  • 19,153
  • 2
  • 48
  • 54
4

Welp, unfortunately this is the issue about PHP. Try/catch statements will catch Exceptions, but what you're receiving is an old-school PHP error.

You'll have to catch an error like this with: http://php.net/manual/en/function.set-error-handler.php

Either that or check to see if $matrix is a mysqli_result object prior to performing mysqli_fetch_array.

normmcgarry
  • 661
  • 2
  • 6
  • 22
  • Old-school PHP error handling worked for me. Thank you for pointing me in that right direction! – Clomp Feb 11 '18 at 07:22
1

PHP is generating a warning, not an exception. Warnings can't be caught. They are more like compiler warnings in C#.

adhominem
  • 1,104
  • 9
  • 24