【问题标题】:Using additional data in php exceptions在 php 异常中使用附加数据
【发布时间】:2014-04-02 12:57:47
【问题描述】:

我有执行 python cgi 的 php 代码,我想将 python 跟踪(从 cgi 返回)作为额外数据传递给 php 异常我该怎么做以及如何从catch(Exception e) { 获取该值(它应该检查是否额外的价值是否存在)。

我有这样的代码:

$response = json_decode(curl_exec($ch));
if (isset($response->error)) {
    // how to send $response->trace with exception.
    throw new Exception($response->error);
}
return $response->result;

我使用 json-rpc 库,该库应该将该数据返回给用户:

} catch (Exception $e) {
    //catch all exeption from user code
    $msg = $e->getMessage();
    echo response(null, $id, array("code"=>200, "message"=>$msg));
}

我是否需要编写新类型的异常,或者我可以使用普通的Exception 来执行此操作吗?我想发送"data" =>中的所有内容@

【问题讨论】:

    标签: php exception exception-handling


    【解决方案1】:

    目前,您的代码无需任何中间步骤即可将响应文本直接转换为对象。相反,您始终可以只保留序列化(通过 JSON)文本并将其附加到异常消息的末尾。

    $responseText = curl_exec($ch);
    $response = json_decode($responseText);
    if (isset($response->error)) {
        throw new Exception('Error when fetching resource. Response:'.$responseText);
    }
    return $response->result;
    

    然后,您可以在错误日志中恢复“响应:”之后的所有内容,并可选择反序列化或仅读取它。

    顺便说一句,我也不会指望服务器发送 JSON,您应该验证响应文本实际上可以解析为 JSON,如果不是,则返回一个单独的错误。

    【讨论】:

      【解决方案2】:

      您需要扩展 Exception 类:

      class ResponseException extends Exception 
      {
          private $_data = '';
      
          public function __construct($message, $data) 
          {
              $this->_data = $data;
              parent::__construct($message);
          }
      
          public function getData()
          {
              return $this->_data;
          }
      }
      

      投掷时:

      ...
      throw new ResponseException($response->error, $someData);
      ...
      

      当抓到时:

      catch(ResponseException $e) {
          ...
          $data = $e->getData();
          ...
      }
      

      更新 - 动态对象属性(又名 DIRTY WAY)

      作为 OP 询问是否在不扩展 Exception 类的情况下执行此任务,您完全可以跳过 ResponseException 类声明。我真的不建议这样做,除非你有非常充分的理由(更多详情请参阅此主题:https://softwareengineering.stackexchange.com/questions/186439/is-declaring-fields-on-classes-actually-harmful-in-php

      在投掷部分:

      ...
      $e = new Exception('Exception message');
      $e->data = $customData; // we're creating object property on the fly
      throw $e;
      ...
      

      当抓到时:

      catch(Exception $e) {
          $data = $e->data; // Access data property
      }
      

      2018 年 9 月编辑: 由于一些读者发现这个答案很有用,我添加了一个指向另一个 Stack Overflow 问题的链接,该问题解释了使用动态声明的属性的缺点。

      【讨论】:

      • 是否可以在没有新的异常类型的情况下执行此操作,通用异常(当捕获时)如何工作?
      • 这样扩展Exception不违反LSP,因为它改变了构造函数签名?
      • 脏路加1
      • @Glutexo 不确定你的意思是什么?异常类构造函数还有其他可选参数,但扩展时不需要传递。
      • 在php异常手册中找到this comment的答案:"如果你想捕获any异常,不管是什么类型,只要使用@987654331 @,因为所有异常都是内置异常的子类。”
      猜你喜欢
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      相关资源
      最近更新 更多