গুজল ব্যতিক্রম পরিচালনা করুন এবং এইচটিটিপি বডি পান


122

আমি যখন গুজল থেকে ত্রুটিগুলি পরিচালনা করতে চাই যখন সার্ভারটি 4XX এবং 5xx স্থিতি কোডগুলি দেয়। আমি এই জাতীয় অনুরোধ করছি:

$client = $this->getGuzzleClient();
$request = $client->post($url, $headers, $value);
try {
    $response = $request->send();
    return $response->getBody();
} catch (\Exception $e) {
    // How can I get the response body?
}

$e->getMessageকোড তথ্য দেয় কিন্তু HTTP প্রতিক্রিয়াটির মূল অংশ দেয় না। আমি কীভাবে প্রতিক্রিয়া বডি পেতে পারি?


1
এই প্রশ্নটি এই প্রশ্নের সাথে সম্পর্কিত stackoverflow.com/questions/17658283/… এবং উত্তরগুলিও কিছুটা সহায়ক হতে পারে।
ট্রেন্ডফিশার

উত্তর:


84

গুজল ৩.x

প্রতি ডক্স , আপনি (উপযুক্ত ব্যতিক্রম টাইপ ধরতে পারে ClientErrorResponseException4xx ত্রুটির জন্য) এবং তার কল getResponse()প্রতিক্রিয়া বস্তু পেতে পদ্ধতি, তারপর কল getBody()যে:

use Guzzle\Http\Exception\ClientErrorResponseException;

...

try {
    $response = $request->send();
} catch (ClientErrorResponseException $exception) {
    $responseBody = $exception->getResponse()->getBody(true);
}

পাসিং trueকরতে getBodyফাংশন ইঙ্গিত করছে যে একটি স্ট্রিং হিসাবে প্রতিক্রিয়া শরীর পেতে চান। অন্যথায় আপনি এটি ক্লাসের উদাহরণ হিসাবে পাবেন Guzzle\Http\EntityBody


232

গুজল 6.x

প্রতি ডক্স , ব্যতিক্রম যে ধরনের ধরা করার প্রয়োজন হতে পারে আছে:

  • GuzzleHttp\Exception\ClientException 400-স্তরের ত্রুটির জন্য
  • GuzzleHttp\Exception\ServerException 500-স্তরের ত্রুটির জন্য
  • GuzzleHttp\Exception\BadResponseException উভয়ের জন্য (এটি তাদের সুপারক্লাস)

এই জাতীয় ত্রুটিগুলি পরিচালনা করার কোডটি এখন এর মতো কিছু দেখায়:

$client = new GuzzleHttp\Client;
try {
    $client->get('http://google.com/nosuchpage');    
}
catch (GuzzleHttp\Exception\ClientException $e) {
    $response = $e->getResponse();
    $responseBodyAsString = $response->getBody()->getContents();
}

12
আমার জন্য $response->getBody()->getContents()একটি খালি স্ট্রিং ফিরে আসবে। আমি তখন এই জুড়ে পদস্খলিত ডক্স : \GuzzleHttp\Psr7\str($e->getResponse()) প্রতিক্রিয়া কাস্টিং হিসাবে একটি Psr7 স্ট্রিং আমাকে একটা দারুণভাবে ফর্ম্যাট এবং সম্পূর্ণ ত্রুটির বার্তা পেয়েছিলাম।
অ্যান্ডি প্লেস

3
@ অ্যান্ডিপ্লেস পিএসআর at এ এক নজরে নেওয়ার পরে (যা আমি এই উত্তরটি লেখার সময় লিঙ্ক করেছি সেই দস্তাবেজের বিভাগ দ্বারা এটি উল্লেখ করা হয়নি, তবে এখনই) কেন তা কল করার Psr7\str()বিভিন্ন ফলাফল হবে তা আমার কাছে তাত্ক্ষণিকভাবে স্পষ্ট নয় calling to ->getContents()। এটি প্রমাণ করার কোনও ন্যূনতম উদাহরণ রয়েছে কি, এটি আমাকে বুঝতে এবং সম্ভবত এই উত্তরটি আপডেট করতে পারে?
মার্ক আমেরিকা

24
উল্লেখযোগ্য যে, 'http_errors' => falseগুজল অনুরোধে বিকল্পটি পাস করা যেতে পারে যা ছোঁড়া ব্যতিক্রমগুলি অক্ষম করে। তারপরে আপনি $response->getBody()স্ট্যাটাস কোডটি নির্বিশেষে দেহটি পেতে পারেন এবং প্রয়োজনে আপনি স্থিতি কোডটি পরীক্ষা করতে পারেন $response->getStatusCode()
কাঁপানো

2
@ অ্যান্ডিপ্লেস হিসাবে, $response->getBody()->getContents()আমাকে এক ক্ষেত্রে একটি খালি স্ট্রিং দেয়, কেন তা আমি বুঝতে পারি না। তবে ব্যবহার করে \GuzzleHttp\Psr7\str()সমস্ত HTTP প্রতিক্রিয়াটিকে স্ট্রিং হিসাবে ফিরিয়ে দেয় এবং আমি কেবল এইচটিটিপি বডি চাই। ডকুমেন্টেশনে যেমন বলা হয়েছে , শরীরটি স্ট্রিংয়ে কাস্ট করে ব্যবহার করা যেতে পারে। $stringBody = (string) $clientException->getResponse()->getBody();
অ্যান্থনিবি

1
এটি আমার জন্য এটি করেছে, যদিও আমি তার \GuzzleHttp\Exception\RequestExceptionপরিবর্তে পাচ্ছিলাম যা একটি 400স্ট্যাটাস কোড ফিরিয়ে দিয়েছে । try $ অনুরোধ-> এপিআই ('পোস্ট', 'শেষ পয়েন্ট.জসন') চেষ্টা করুন; } ধরা (অনুরোধ এক্সপ্লেশন $ ই) {মুদ্রণ_আর ($ ই-> getResponse () -> getBody () -> getContents ()); }
jpcaparas

54

যদিও উপরের উত্তরগুলি ভাল তারা নেটওয়ার্ক ত্রুটিগুলি ধরবে না। মার্ক যেমন উল্লেখ করেছেন, BadResponseException ক্লায়েন্টএক্সসেপশন এবং সার্ভারএক্সসেপ্টের জন্য কেবল একটি সুপার ক্লাস। তবে রিকোয়েস্টএক্সেপশনও ব্যাডরেসপোনসিপেশনের একটি সুপার ক্লাস। রিকোয়েস্ট এক্সসেপশনটি কেবল 400 এবং 500 ত্রুটি নয় তবে নেটওয়ার্ক ত্রুটি এবং অসীম পুনঃনির্দেশগুলিও নিক্ষেপ করা হবে। সুতরাং আসুন আমরা নীচের পৃষ্ঠার জন্য অনুরোধ করি তবে আপনার নেটওয়ার্কটি চলছে এবং আপনার ক্যাচটি কেবলমাত্র একটি ব্যান্ডস্পেসেক্সেপশন আশা করছে। ভাল আপনার অ্যাপ্লিকেশন একটি ত্রুটি নিক্ষেপ করবে।

এই ক্ষেত্রে অনুরোধ প্রত্যাশা করা এবং প্রতিক্রিয়ার জন্য চেক করা ভাল।

try {
  $client->get('http://123123123.com')
} catch (RequestException $e) {

  // If there are network errors, we need to ensure the application doesn't crash.
  // if $e->hasResponse is not null we can attempt to get the message
  // Otherwise, we'll just pass a network unavailable message.
  if ($e->hasResponse()) {
    $exception = (string) $e->getResponse()->getBody();
    $exception = json_decode($exception);
    return new JsonResponse($exception, $e->getCode());
  } else {
    return new JsonResponse($e->getMessage(), 503);
  }

}

হয় JsonResponseমদ্যপানোত্সব থেকে একটি বর্গ?
এক্সেল

JsonResponseসিমফনি থেকে আসে
চ্যাপ

14

2019 সালের হিসাবে আমি এখানে উপরের উত্তরগুলি এবং গুজল ডক্স থেকে ব্যতিক্রমটি পরিচালনা করতে, প্রতিক্রিয়াটির বডি, স্ট্যাটাস কোড, বার্তা এবং অন্যান্য কখনও কখনও মূল্যবান প্রতিক্রিয়া আইটেমগুলি বিশদভাবে বর্ণনা করেছি ।

try {
    /**
     * We use Guzzle to make an HTTP request somewhere in the
     * following theMethodMayThrowException().
     */
    $result = theMethodMayThrowException();
} catch (\GuzzleHttp\Exception\RequestException $e) {
    /**
     * Here we actually catch the instance of GuzzleHttp\Psr7\Response
     * (find it in ./vendor/guzzlehttp/psr7/src/Response.php) with all
     * its own and its 'Message' trait's methods. See more explanations below.
     *
     * So you can have: HTTP status code, message, headers and body.
     * Just check the exception object has the response before.
     */
    if ($e->hasResponse()) {
        $response = $e->getResponse();
        var_dump($response->getStatusCode()); // HTTP status code;
        var_dump($response->getReasonPhrase()); // Response message;
        var_dump((string) $response->getBody()); // Body, normally it is JSON;
        var_dump(json_decode((string) $response->getBody())); // Body as the decoded JSON;
        var_dump($response->getHeaders()); // Headers array;
        var_dump($response->hasHeader('Content-Type')); // Is the header presented?
        var_dump($response->getHeader('Content-Type')[0]); // Concrete header value;
    }
}
// process $result etc. ...

Voila। আপনি স্বতন্ত্রভাবে পৃথক করা আইটেমগুলিতে প্রতিক্রিয়াটির তথ্য পাবেন।

পার্শ্ব নোট:

সঙ্গে catchদফা আমরা উত্তরাধিকার শৃঙ্খল পিএইচপি রুট ব্যতিক্রম বর্গ ধরা \Exception যেমন মদ্যপানোত্সব কাস্টম ব্যতিক্রম এটা প্রসারিত।

লারাভেল বা এডাব্লুএস এপিআই পিএইচপি এসডিকে যেমন গুজলটি হুডের নীচে ব্যবহার করা হয় সেই ক্ষেত্রে ব্যবহারের ক্ষেত্রে এটি কার্যকর হতে পারে যাতে আপনি আসল গুজল ব্যতিক্রমটি ধরতে পারবেন না।

এই ক্ষেত্রে, গুজল ডক্সে বর্ণিত ব্যতিক্রম শ্রেণিটি নাও হতে পারে (উদাঃ GuzzleHttp\Exception\RequestException গুজলের মূল ব্যতিক্রম হিসাবে)।

সুতরাং আপনি ধরতে হবে \Exception পরিবর্তে হবে তবে মনে রাখবেন এটি এখনও গুজল ব্যতিক্রম শ্রেণির উদাহরণ।

যদিও যত্ন সহ ব্যবহার করুন। এই মোড়কগুলি গুজল $e->getResponse()অবজেক্টের আসল পদ্ধতিগুলি উপলভ্য নয়। এই ক্ষেত্রে, আপনাকে মোড়কের আসল ব্যতিক্রম উত্স কোডটি দেখতে হবে এবং গুজল ব্যবহার না করে স্থিতি, বার্তা ইত্যাদি কীভাবে পাবেন তা খুঁজে বের করতে হবে$response পদ্ধতিগুলি ।

আপনি যদি গুজলকে সরাসরি নিজের কাছে কল করেন তবে আপনি তাদের ব্যবহারের অবস্থার সাথে সম্মতি জানিয়ে তাদের ব্যতিক্রম ডক্সেGuzzleHttp\Exception\RequestException বর্ণিত অন্য যে কোনওটিকে ধরতে পারেন ।


1
আপনি যদি পরীক্ষা না করে থাকেন $responseতবে ব্যতিক্রমগুলি পরিচালনা করার সময় আপনার অবজেক্টে পদ্ধতিগুলি কল করা উচিত নয় $e->hasResponse(), অন্যথায় $responseহতে পারে nullএবং কোনও পদ্ধতি কলগুলি মারাত্মক ত্রুটির কারণ হতে পারে ।
22 তে প্রসারণ করা

@ উদ্বিগ্ন, সত্য। ঠিক যেমন গুজল ব্যতিক্রম ডক্স বলেছে। উত্তর আপডেট করেছেন। ধন্যবাদ.
ভ্যালেন্টাইন শি

1
... তবে এটি ঠিক হওয়ার পরেও সমস্যাযুক্ত। আপনি সমস্ত ব্যতিক্রমগুলি ধরছেন, কেবল গুজলগুলিই নয়, তবে আপনি ফলাফলটির দিকে আহ্বান করছেন $e->hasResponse, এমন একটি পদ্ধতি যা অবশ্যই গুজল ব্যতিক্রমগুলির জন্য বিদ্যমান নয়। সুতরাং আপনি যদি কোনও অ-গুজল ব্যতিক্রম উত্থাপন করেন তবে theMethodMayThrowException()এই কোডটি এটি ধরবে, অস্তিত্বহীন পদ্ধতিটিকে কল করার চেষ্টা করবে এবং অস্তিত্বহীন পদ্ধতির কারণে ক্র্যাশ হবে, কার্যকরভাবে ত্রুটির আসল কারণটি গোপন করে। এটি এড়াতে GuzzleHttp\Exception\RequestExceptionপরিবর্তে ধরা ভাল Exception
মার্ক আমেরিকা

1
@ মার্কআমেরি, আপনার পয়েন্টটি পুরোপুরি বৈধ। ধন্যবাদ. আমি উত্তর বডি আপডেট।
ভ্যালেন্টাইন শি

1
@ জাবরআলনাহিয়ান শুনে খুশি হয়েছিল :) এটিই আমার উদ্দেশ্য। সর্বদা স্বাগতম.
ভ্যালেন্টাইন শি

4

যদি করা 'http_errors' => falseমদ্যপানোত্সব অনুরোধ বিকল্পগুলিতে, তাহলে এটি বন্ধ করে দেয় থ্রো ব্যতিক্রম যখন পেতে 4xx বা 5xx ত্রুটি, এরকম: $client->get(url, ['http_errors' => false])। তারপরে আপনি প্রতিক্রিয়াটি পার্স করুন, ঠিক আছে বা ত্রুটি হওয়া উচিত নয়, এটি আরও তথ্যের জন্য প্রতিক্রিয়াতে হবে


এই প্রশ্নটি হ্যান্ডেল ত্রুটিগুলি সম্পর্কিত যা ত্রুটি ব্যতিক্রমগুলি বন্ধ করার জন্য জিজ্ঞাসা করছে না
Dlk
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.