गुज़ले से अपवादों को पकड़ना


80

मैं परीक्षण के एक सेट से अपवादों को पकड़ने की कोशिश कर रहा हूं, मैं एक एपीआई पर चल रहा हूं जिसे मैं विकसित कर रहा हूं और मैं एपीआई विधियों का उपभोग करने के लिए गुझेल का उपयोग कर रहा हूं। मुझे परीक्षण एक कोशिश / पकड़ ब्लॉक में लिपटे हुए हैं लेकिन यह अभी भी बिना किसी अपवाद वाली त्रुटियों को फेंक रहा है। एक इवेंट श्रोता को उनके डॉक्स में वर्णित के रूप में जोड़ना कुछ भी नहीं लगता है। मुझे उन प्रतिक्रियाओं को पुनः प्राप्त करने में सक्षम होना चाहिए जिनके 500, 401, 400 के HTTP कोड हैं, वास्तव में कुछ भी नहीं है जो कि 200 नहीं है क्योंकि सिस्टम कॉल के परिणाम के आधार पर सबसे उपयुक्त कोड सेट करेगा यदि यह काम नहीं करता है ।

वर्तमान कोड उदाहरण

foreach($tests as $test){

        $client = new Client($api_url);
        $client->getEventDispatcher()->addListener('request.error', function(Event $event) {        

            if ($event['response']->getStatusCode() == 401) {
                $newResponse = new Response($event['response']->getStatusCode());
                $event['response'] = $newResponse;
                $event->stopPropagation();
            }            
        });

        try {

            $client->setDefaultOption('query', $query_string);
            $request = $client->get($api_version . $test['method'], array(), isset($test['query'])?$test['query']:array());


          // Do something with Guzzle.
            $response = $request->send();   
            displayTest($request, $response);
        }
        catch (Guzzle\Http\Exception\ClientErrorResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch (Guzzle\Http\Exception\ServerErrorResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch (Guzzle\Http\Exception\BadResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch( Exception $e){
            echo "AGH!";
        }

        unset($client);
        $client=null;

    }

यहां तक ​​कि फेंके गए अपवाद प्रकार के लिए विशिष्ट कैच ब्लॉक के साथ मैं अभी भी वापस आ रहा हूं

Fatal error: Uncaught exception 'Guzzle\Http\Exception\ClientErrorResponseException' with message 'Client error response [status code] 401 [reason phrase] Unauthorized [url]

और जैसा कि आप उम्मीद करेंगे पेज पर सभी निष्पादन बंद हो जाता है। BadResponseException कैच के अलावा ने मुझे 404s सही से पकड़ने की अनुमति दी, लेकिन यह 500 या 401 प्रतिक्रियाओं के लिए काम नहीं करता है। क्या कोई सुझाव दे सकता है कि मैं कहां गलत हूं।


3
क्या यह कोड किसी नाम स्थान के अंतर्गत है? यदि ऐसा है, तो जब तक आप useअपवाद नहीं हैं, आपको एफक्यू क्लास को स्पष्ट रूप से बताने के लिए उन्हें `` के साथ उपसर्ग करने की आवश्यकता हो सकती है। इसलिए, उदाहरण के लिए, '\ Guzzle \ Http \ Exception \ ClientErrorResponseException'
Anthony Sterling

जवाबों:


17

यदि अपवाद को उस tryब्लॉक में फेंक दिया जा रहा है, तो सबसे खराब स्थिति में Exceptionकिसी भी चीज को बिना पकड़े पकड़ा जाना चाहिए।

विचार करें कि परीक्षण का पहला भाग अपवाद को फेंक रहा है और tryब्लॉक में भी लपेटता है ।


1
आप सही हैं, कोशिश / कैच के बाहर एक परीक्षण था जो अपवाद को फेंक रहा था। मूर्खतापूर्ण गलती, मदद के लिए धन्यवाद।
एरिक

146

आपकी परियोजना के आधार पर, गज़ल के अपवादों को अक्षम करना आवश्यक हो सकता है। कभी-कभी कोडिंग नियम प्रवाह नियंत्रण के अपवादों को अस्वीकार कर देते हैं। आप इस तरह गज़ल 3 के लिए अपवादों को निष्क्रिय कर सकते हैं :

$client = new \Guzzle\Http\Client($httpBase, array(
  'request.options' => array(
     'exceptions' => false,
   )
));

यह टाइमआउट जैसी किसी चीज़ के लिए कर्ल अपवादों को अक्षम नहीं करता है, लेकिन अब आप आसानी से हर स्टेटस कोड प्राप्त कर सकते हैं:

$request = $client->get($uri);
$response = $request->send();
$statuscode = $response->getStatusCode();

जाँच करने के लिए, यदि आपको एक वैध कोड मिला है, तो आप कुछ इस तरह का उपयोग कर सकते हैं:

if ($statuscode > 300) {
  // Do some error handling
}

... या बेहतर सभी अपेक्षित कोड संभालें:

if (200 === $statuscode) {
  // Do something
}
elseif (304 === $statuscode) {
  // Nothing to do
}
elseif (404 === $statuscode) {
  // Clean up DB or something like this
}
else {
  throw new MyException("Invalid response from api...");
}

गुझिल 5.3 के लिए

$client = new \GuzzleHttp\Client(['defaults' => [ 'exceptions' => false ]] );

@ मीका को धन्यवाद

गुझेल 6 के लिए

$client = new \GuzzleHttp\Client(['http_errors' => false]);

10
कभी एक लापता होने के कारण एक अजीब बग था break;; मैं पसंद करता हूँ if, स्विच का समर्थन करता है ==
ट्रेंडफिशर 12

उल्लेख करने के लिए धन्यवाद request.options। मेरी समस्या का समाधान किया और मुझे इसे ठीक से देखने में बचाया। :)
डैनियल एमआर

2
या Guzzle5.3 में: $ ग्राहक = new \ GuzzleHttp \ Client (['चूक' => ['अपवाद' => गलत]]);
मिका

यह एक आवश्यक परियोजना पर मेरी बेकन को बचाया। धन्यवाद ट्रेंडफिशर और एसओ!
डैन बैरन

46

गुज़ले त्रुटियों को पकड़ने के लिए आप कुछ इस तरह से कर सकते हैं:

try {
    $response = $client->get('/not_found.xml')->send();
} catch (Guzzle\Http\Exception\BadResponseException $e) {
    echo 'Uh oh! ' . $e->getMessage();
}

... लेकिन, आपके अनुरोध को "लॉग" या "पुनः भेजें" करने में सक्षम होने के लिए कुछ इस तरह की कोशिश करें:

// Add custom error handling to any request created by this client
$client->getEventDispatcher()->addListener(
    'request.error', 
    function(Event $event) {

        //write log here ...

        if ($event['response']->getStatusCode() == 401) {

            // create new token and resend your request...
            $newRequest = $event['request']->clone();
            $newRequest->setHeader('X-Auth-Header', MyApplication::getNewAuthToken());
            $newResponse = $newRequest->send();

            // Set the response object of the request without firing more events
            $event['response'] = $newResponse;

            // You can also change the response and fire the normal chain of
            // events by calling $event['request']->setResponse($newResponse);

            // Stop other events from firing when you override 401 responses
            $event->stopPropagation();
        }

});

... या यदि आप "ईवेंट प्रचार को रोकना चाहते हैं" तो आप ईवेंट श्रोता (-255 से अधिक प्राथमिकता के साथ) को रोक सकते हैं और ईवेंट प्रचार को रोक सकते हैं।

$client->getEventDispatcher()->addListener('request.error', function(Event $event) {
if ($event['response']->getStatusCode() != 200) {
        // Stop other events from firing when you get stytus-code != 200
        $event->stopPropagation();
    }
});

गुगल त्रुटियों को रोकने के लिए एक अच्छा विचार है:

request.CRITICAL: Uncaught PHP Exception Guzzle\Http\Exception\ClientErrorResponseException: "Client error response

आपके आवेदन में


6
यह अब गुज़ेले 6 में संभव नहीं है। किसी भी विचार को एक मिडलवेयर के साथ कैसे करना है?
फेनगेल

30

मेरे मामले में मैं Exceptionएक नामांकित फ़ाइल पर फेंक रहा था , इसलिए php ने पकड़ने की कोशिश कीMy\Namespace\Exception इसलिए किसी भी अपवाद को नहीं पकड़ा।

catch (Exception $e)सही जाँच हो रही हैException क्लास ।

बस catch (\Exception $e)(उस के साथ \) प्रयास करें और देखें कि क्या यह काम करता है।


4
काश मैंने पहली बार एक ही सवाल किया हो तो मैंने इस त्रुटि को स्क्रॉल किया था। मेरे लिए मैं पुराने गज़ल अपवाद नामों का उपयोग कर रहा था और सामान्य अपवाद को नहीं पकड़ रहा था क्योंकि मैं मूल नामस्थान पर नहीं था। अपवाद से पहले बैकस्लैश को जोड़ना सामान्य अपवाद को पकड़ना शुरू कर दिया जिससे मुझे अपने नाम बेमेल त्रुटियों को और अधिक विशिष्ट गुज़ल अपवादों पर देखने की अनुमति मिली। पर टिप्पणी देखें stackoverflow.com/a/7892917/2829359
कार्सन इवांस

यह सटीक मुद्दा था जो मेरे पास भी था। अच्छा उत्तर
प्रसाद राजपक्ष


5

पुराना सवाल है, लेकिन गज़ल अपवाद वस्तु के भीतर प्रतिक्रिया जोड़ता है। तो एक साधारण कोशिश पर पकड़ GuzzleHttp\Exception\ClientExceptionऔर फिर getResponseउस अपवाद का उपयोग करके यह देखना कि 400-स्तरीय त्रुटि और वहाँ से क्या जारी है।


2

मैं पकड़ रहा था GuzzleHttp\Exception\BadResponseExceptionजैसे @dado सुझाव दे रहा है। लेकिन एक दिन मुझे मिला GuzzleHttp\Exception\ConnectExceptionजब डोमेन के लिए DNS उपलब्ध नहीं था। तो मेरा सुझाव है - GuzzleHttp\Exception\ConnectExceptionडीएनएस त्रुटियों के बारे में भी सुरक्षित होने के लिए पकड़ ।


लगता है कि आप को पकड़ना चाहिए, GuzzleHttp\Exception\RequestExceptionजो माता-पिता का है ConnectException, BadResponseExceptionऔर TooManyRedirectsException
लौ

1

मैं Psr-7 Guzzle, Guzzle7 और HTTPClient (लार्वा द्वारा प्रदान किए जाने वाले Guzzle HTTP क्लाइंट के आसपास न्यूनतम, एपीआई) में अपवाद हैंडलिंग के उत्तर को अपडेट करना चाहता हूं।

गुज़ले 7 (गुज़ले 6 के लिए भी यही काम करता है)

RequestException , RequestException का उपयोग करके किसी भी अपवाद को पकड़ता है जिसे अनुरोधों को स्थानांतरित करते समय फेंक दिया जा सकता है।

try{
  $client = new \GuzzleHttp\Client(['headers' => ['Authorization' => 'Bearer ' . $token]]);
  
  $guzzleResponse = $client->get('/foobar');
  // or can use
  // $guzzleResponse = $client->request('GET', '/foobar')
    if ($guzzleResponse->getStatusCode() == 200) {
         $response = json_decode($guzzleResponse->getBody(),true);
         //perform your action with $response 
    } 
}
catch(\GuzzleHttp\Exception\RequestException $e){
   // you can catch here 400 response errors and 500 response errors
   // You can either use logs here use Illuminate\Support\Facades\Log;
   $error['error'] = $e->getMessage();
   $error['request'] = $e->getRequest();
   if($e->hasResponse()){
       if ($e->getResponse()->getStatusCode() == '400'){
           $error['response'] = $e->getResponse(); 
       }
   }
   Log::error('Error occurred in get request.', ['error' => $error]);
}catch(Exception $e){
   //other errors 
}

Psr7 गज़ल

use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\RequestException;

try {
    $client->request('GET', '/foo');
} catch (RequestException $e) {
    $error['error'] = $e->getMessage();
    $error['request'] = Psr7\Message::toString($e->getRequest());
    if ($e->hasResponse()) {
        $error['response'] = Psr7\Message::toString($e->getResponse());
    }
    Log::error('Error occurred in get request.', ['error' => $error]);
}

HTTPClient के लिए

use Illuminate\Support\Facades\Http;
try{
    $response = Http::get('http://api.foo.com');
    if($response->successful()){
        $reply = $response->json();
    }
    if($response->failed()){
        if($response->clientError()){
            //catch all 400 exceptions
            Log::debug('client Error occurred in get request.');
            $response->throw();
        }
        if($response->serverError()){
            //catch all 500 exceptions
            Log::debug('server Error occurred in get request.');
            $response->throw();
        }
        
    }
 }catch(Exception $e){
     //catch the exception here
 }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.