如何在PhP中使用SoapWrapper捕获致命错误异常


How to catch FatalError Exception using SoapWrapper in PhP

我在应用程序中使用Laravel SoapClient Wrapper进行Soap调用。我把它用作模型扩展,这样我就可以在每个需要soap调用的控制器中轻松地使用它。到目前为止一切都很好,但我想确保我的应用程序不会在WSDL URL不正确或SOAP服务器上不存在服务调用等情况下崩溃。我试图"尝试捕获"代码的这些部分,但没有成功。我的代码是下一个:

use Artisaninweb'SoapWrapper'Extension'SoapService;
use Artisaninweb'SoapWrapper'Facades'SoapWrapper;
class Wsdl extends SoapService{
  protected $name = 'test';
  protected $wsdl;
  protected $trace = true;
  public function __construct($wsdl)
  {
    $this->wsdl = $wsdl;
    SoapWrapper::add(function ($service) {
        $service
            ->name($this->name)
            ->wsdl($this->wsdl)
            ->trace(true);
    });
  }
  public function functions()
  {
    return $this->getFunctions();
  }
  public function bills(Array $data)
  {   //function for get bills for one customer
    $bill= null;
    try{
        SoapWrapper::service($this->name, function ($service) use ($data, &$bill) {
            $bill= $service->call('getBill', [$data])->billStructure;
        });
        return $bill;
    }
    catch('SoapFault $e){
        //dd("soapFault");
        return null;
    }
    catch('ErrorException $e){
        //dd("errorException");
        return null;
    }
  }   
}      

在我的控制器中,我称这种型号为

try{
  $soap = new Wsdl('link');   
  $data = [
   'param' => 1
  ];
  $result= $soap->bills($data);             
}
catch('Exception  $e){
//problem 
  flash()->error("There was a problem with getting data, try to contact administrator");
}
catch('FatalErrorException  $e){
  //problem 
  flash()->error("There was a problem with getting data, try to contact administrator");
}

我设法发现了两个错误:

  1. 如果我在中有不存在的XML结构(响应的XML名称错误)

$bill=$service->call('getBill',[$data])->billStructure

  1. 如果我在$bill=$service->call('getBill',[$data])->billStructure中有错误的服务名称

我抓不到的错误是:

如果我的WSDL链接错误(不正确),那么我会得到

服务中的致命错误异常。php第356行:SOAP-错误:分析WSDL:无法从"链接"加载:无法加载外部实体"链接"

所以我的问题是如何处理该异常,以便向我的应用程序的用户提供消息(获取数据时出现问题,请尝试联系管理员…)?

在我的代码中,你可以看到我尝试过某种Try-Catch,但没有成功,所以任何建议都很好。

问题出现在Laravel框架中。Laravel将此错误解释为致命错误,并因此中止了我的应用程序。我使用的是Laravel 5.1。为了完成这项工作,他不得不改变一些总体设置。

在应用程序''异常中,您需要添加一些框架忽略致命错误异常的代码。默认情况下,函数render()看起来像这个

public function render($request, Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    }
    return parent::render($request, $e);
}

要使这个错误不会崩溃你的应用程序添加一个额外的条件,然后功能看起来像这个

public function render($request, Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    }
    if(strpos($e->getMessage(), 'SOAP-ERROR') !== false)
    {
        return false;
    }
    return parent::render($request, $e);
}

我认为,在1天的失败后,这是最好的解决方案(当然,如果你使用Laravel 5.1).对于纯php有几种方法可以做到:

  1. 编写自己的错误处理程序
  2. 打开和关闭x_debug
  3. 尝试从不正确的wsdl中获取内容,然后以某种方式进行验证
//Could manipulate:
public function render($request, Exception $e)
    {
        switch (get_class($e)) {
            case 'SoapFault':
                return 'Erro do serviço no cliente: '.$e->faultstring;
                break;
            default:
                return parent::render($request, $e);
                break;
        }        
    }