Tuesday, 6 September 2016

php - Can I try/catch a warning?




I need to catch some warnings being thrown from some php native functions and then handle them.



Specifically:



array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )


It throws a warning when the DNS query fails.



try/catch doesn't work because a warning is not an exception.




I now have 2 options:




  1. set_error_handler seems like overkill because I have to use it to filter every warning in the page (is this true?);


  2. Adjust error reporting/display so these warnings don't get echoed to screen, then check the return value; if it's false, no records is found for hostname.




What's the best practice here?


Answer




Set and restore error handler



One possibility is to set your own error handler before the call and restore the previous error handler later with restore_error_handler().



set_error_handler(function() { /* ignore errors */ });
dns_get_record();
restore_error_handler();


You could build on this idea and write a re-usable error handler that logs the errors for you.




set_error_handler([$logger, 'onSilencedError']);
dns_get_record();
restore_error_handler();


Turning errors into exceptions



You can use set_error_handler() and the ErrorException class to turn all php errors into exceptions.




set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {
// error was suppressed with the @-operator
if (0 === error_reporting()) {
return false;
}

throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try {

dns_get_record();
} catch (ErrorException $e) {
// ...
}


The important thing to note when using your own error handler is that it will bypass the error_reporting setting and pass all errors (notices, warnings, etc.) to your error handler. You can set a second argument on set_error_handler() to define which error types you want to receive, or access the current setting using ... = error_reporting() inside the error handler.



Suppressing the warning




Another possibility is to suppress the call with the @ operator and check the return value of dns_get_record() afterwards. But I'd advise against this as errors/warnings are triggered to be handled, not to be suppressed.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...