简体   繁体   中英

How to catch FatalError Exception using SoapWrapper in PhP

I'm using Laravel SoapClient Wrapper for Soap calls in my application. I use it as model extension so I can use it easily in each controller which needs soap calls. So far is all excellent, but i wanna be sure that my app don't crash if WSDL URL is incorrect or service call doesn't exist on SOAP server etc... I tried to "try-catch" those parts of code but i wasn't successful. My code is next :

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;
    }
  }   

}      

In my controller i call this model like this

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");
}

I managed to catch 2 errors:

  1. If i have non existing structure of XML (wrong name of xml for response) in

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

  1. If i have wrong name of service in $bill= $service->call(' getBill ', [$data])->billStructure

Error which i can't catch is:

If my WSDL link is wrong (incorrect) then i get

FatalErrorException in Service.php line 356: SOAP-ERROR: Parsing WSDL: Couldn't load from 'link' : failed to load external entity "link"

So my question is how to handle that Exception so i can provide a message to a user of my app (There was a problem with getting data, try to contact administrator...)?

In my code you can see that i have tried some kind of Try-Catch but didn't worked, so any advice would be nice.

The problem was in Laravel framework. Laravel interpreted this error as fatal error and aborted my app as a result. I am using Laravel 5.1. and to make this work had to change some of his general settings.

In app\\Exceptions you need to add some code that framework ignores that FatalError Exception. By default function render() looks like this

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

To make this error wont crash your application add one additional condition and then function looks like this

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);
}

I think that after 1 day of losing for making this work, this is the best solution (of course if you use Laravel 5.1). For pure php there are several ways to do it :

  1. write your own error handler
  2. turn on and off x_debug
  3. try to get content from incorrect wsdl and then somehow verify it
//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;
        }        
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM