Can I try/catch a warning?

前端 未结 11 1032
孤城傲影
孤城傲影 2020-11-22 01:04

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

Specifically:

array dns_get_record  ( string $hostnam         


        
相关标签:
11条回答
  • 2020-11-22 01:50

    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.

    0 讨论(0)
  • 2020-11-22 01:50

    Normaly you should never use @ unless this is the only solution. In that specific case the function dns_check_record should be use first to know if the record exists.

    0 讨论(0)
  • 2020-11-22 01:52

    Combining these lines of code around a file_get_contents() call to an external url helped me handle warnings like "failed to open stream: Connection timed out" much better:

    set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
    {
        throw new ErrorException( $err_msg, 0, $err_severity, $err_file, $err_line );
    }, E_WARNING);
    try {
        $iResult = file_get_contents($sUrl);
    } catch (Exception $e) {
        $this->sErrorMsg = $e->getMessage();
    }
    restore_error_handler();
    

    This solution works within object context, too. You could use it in a function:

    public function myContentGetter($sUrl)
    {
      ... code above ...
      return $iResult;
    }
    
    0 讨论(0)
  • 2020-11-22 01:53

    The solution that really works turned out to be setting simple error handler with E_WARNING parameter, like so:

    set_error_handler("warning_handler", E_WARNING);
    dns_get_record(...)
    restore_error_handler();
    
    function warning_handler($errno, $errstr) { 
    // do something
    }
    
    0 讨论(0)
  • 2020-11-22 01:59

    You should probably try to get rid of the warning completely, but if that's not possible, you can prepend the call with @ (i.e. @dns_get_record(...)) and then use any information you can get to figure out if the warning happened or not.

    0 讨论(0)
提交回复
热议问题