如何覆盖异常类而不显示致命错误

时间:2022-12-04 20:29:54

I am trying to write a class that communicate with an API. I would like to override the standard Exception class in PHP to return the message, error code that I want.

我正在尝试编写一个与API通信的类。我想覆盖PHP中的标准Exception类来返回消息,我想要的错误代码。

I have added this extension

我添加了此扩展程序

<?php namespace API;

/**
 * API Exception
 *
 * @package ICWS
 */
class ApiException extends \Exception
{
    public function __construct($message, $code = 0)
    {
        // Custom ICWS API Exception Message
        $apiMessage = 'ICWS API Error: ' . $message;

        //More code to come to custom the error message/code.....

        // Run parent construct using custom message
        parent::__construct($apiMessage, $code);
    }
}
?> 

Then when needed I create new ApiException like so

然后在需要时我创建新的ApiException

    throw new ApiException($errorMessage, $errorNo);

Finally I wrap the function that throws an exception by try{} catch() block to capture the exception.

最后,我通过try {} catch()块来包装抛出异常的函数来捕获异常。

However, I still get the a fatal error instead of just the message that I provided.

但是,我仍然得到一个致命错误,而不仅仅是我提供的消息。

Here is my code

这是我的代码

public function createSession($userID, $password){

    $data = array('userID' => $userID,
                  'password' => $password);

    try {

        $data = $this->_makeCall('POST', 'connection', $data);

        $this->_csrfToken = $data['csrfToken'];
        $this->_sessionId = $data['sessionId'];
        $this->_alternateHostList = $data['alternateHostList'];

    } catch (Exception $e){
        $this->_displayError($e);
    }
}

private function _makeCall($uri, $data = false, $header = array())
{
    $ch = curl_init();
    $url = $this->_baseURL . $uri;

    //disable the use of cached connection
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);

    curl_setopt($ch, CURLOPT_URL, $url);

    //return the respond from the API
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    if(!empty($header)){
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }

    curl_setopt($ch, CURLOPT_POST, true);

    if ($data){
        $JSON = json_encode( $data );
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $JSON );
    }


    $result = curl_exec($ch);

    //throw cURL exception
    if($result === false){
        $errorNo = curl_errno($ch);
        $errorMessage = curl_error($ch);

        throw new ApiException($errorMessage, $errorNo);
    }   

    $result = json_decode($result, true);

    //throw API exception
    if(  $this->_hasAPIError($result) )
    ){          
        throw new ApiException($result['message'], 0);
    }

    return $result;
}

private function _displayError(Exception $e){
    echo 'Error Number: ' . $e->getCode() . "\n";
    echo 'Error Description: ' . $e->getMessage() . "\n\n";     
}

private function _hasAPIError($result){
    if(    isset($result['errorId']) && !empty($result['errorId'])
        && isset($result['errorCode']) && !empty($result['errorCode'])
        && isset($result['message']) && !empty($result['message'])
    ){          
        return true;
    }

    return false;       
}

I would like to see something like this at then end "if there is an error"

我希望在此结束时看到类似的内容“如果有错误”

Error Number: 0
Error Description: ICWS API Error: The authentication process failed

This is what I currently get

这就是我目前得到的

Fatal error: Uncaught exception 'API\ApiException' with message 'ICWS API Error: The authentication process failed.' in C:\phpsites\icws\API\ICWS.php:130 Stack trace: #0 C:\phpsites\icws\API\ICWS.php(57): API\ICWS->_makeCall('connection', Array) #1 C:\phpsites\icws\index.php(17): API\ICWS->createSession('user', 'pass') #2 {main} thrown in C:\phpsites\icws\API\ICWS.php on line 130

2 个解决方案

#1


The error is that you are catching Exception, not ApiException. Try this:

错误是您正在捕获异常,而不是ApiException。试试这个:

try {
    $data = $this->_makeCall('POST', 'connection', $data);
    $this->_csrfToken = $data['csrfToken'];
    $this->_sessionId = $data['sessionId'];
    $this->_alternateHostList = $data['alternateHostList'];
} catch (ApiException $e){ // Here is the change: Exception to ApiException
    $this->_displayError($e);
}

#2


You did not import the Exception class into your namespace, so when doing catch (Exception $e), Exception is an unknown class (because PHP is assuming API\Exception) and PHP will not notice that APIException is a subclass of Exception. Curiously, PHP does not complain about catching a non-existing class (I've just confirmed this locally with PHP 5.6.8).

您没有将Exception类导入到命名空间中,因此在执行catch(Exception $ e)时,Exception是一个未知类(因为PHP假定为API \ Exception),PHP不会注意到APIException是Exception的子类。奇怪的是,PHP并没有抱怨捕获一个不存在的类(我刚刚用PHP 5.6.8在本地确认了这一点)。

The following should work:

以下应该有效:

catch (\Exception $e) {
    // ...
}

Alternatively:

use Exception;
// ...
catch (\Exception $e) {
    // ...
}

#1


The error is that you are catching Exception, not ApiException. Try this:

错误是您正在捕获异常,而不是ApiException。试试这个:

try {
    $data = $this->_makeCall('POST', 'connection', $data);
    $this->_csrfToken = $data['csrfToken'];
    $this->_sessionId = $data['sessionId'];
    $this->_alternateHostList = $data['alternateHostList'];
} catch (ApiException $e){ // Here is the change: Exception to ApiException
    $this->_displayError($e);
}

#2


You did not import the Exception class into your namespace, so when doing catch (Exception $e), Exception is an unknown class (because PHP is assuming API\Exception) and PHP will not notice that APIException is a subclass of Exception. Curiously, PHP does not complain about catching a non-existing class (I've just confirmed this locally with PHP 5.6.8).

您没有将Exception类导入到命名空间中,因此在执行catch(Exception $ e)时,Exception是一个未知类(因为PHP假定为API \ Exception),PHP不会注意到APIException是Exception的子类。奇怪的是,PHP并没有抱怨捕获一个不存在的类(我刚刚用PHP 5.6.8在本地确认了这一点)。

The following should work:

以下应该有效:

catch (\Exception $e) {
    // ...
}

Alternatively:

use Exception;
// ...
catch (\Exception $e) {
    // ...
}