Guzzle returns 500 error - php

So im new to guzzle and building API's , I have used Laravel Passport and on one GET call its fine. I have written a POST call and getting a 500 error in return
Post function
public function newsSingle() {
$request = (new GuzzleHttp\Client)->post('http://138.68.180.100/news/article/single', [
'headers' => [
'Authorization' => 'Bearer '.session()->get('token.access_token'),
'post_id' => $_POST['post_id']
]
]);
$news = json_decode((string)$request->getBody());
return view('pages.newsingle', compact('news'));
}
Which does add the post item
POST Data
post_id
"3"
on the other end I have
Route:
Route::post('news/article/single', 'ApiController#singlePost')->middleware('auth:api');
Controller function:
public function singlePost(Request $request) {
$article = Articles::where('id', $request['post_id'])->get();
return $article;
}
my error:
Server error: `POST http://ipaddress/news/article/single` resulted in a `500 Internal Server Error` response: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="robots" content="noindex,nofollow (truncated...)

We found the similar issue with Guzzle for External API calls when response code is 500 and got Server error: and exception is thrown. There is a work around to do a bypass mechanism by catching the exception due to BadResponseException to return as response. below is the code for performing this. :)
catch (\GuzzleHttp\Exception\BadResponseException $e) {
return $e->getResponse()->getBody()->getContents();
}

Related

Why can't I access the response content when the Symfony HTTP Client encounters an error, and an exception is thrown instead?

I want to make a request to retrieve user info from OAUTH server with Symfony HttpClient but I can't fetch fetch the response directly when encountering an error response, because the client throws an exception.
My UserProvider:
public function loadUserByUsername($username)
{
try {
$response = $this->httpClient->request(
'GET',
$this->baseUrl . '/userinfo',
[
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json'
],
'auth_bearer' => $username
]
);
var_dump($response->toArray());die;
} catch (\Exception $e) {
var_dump($e->getMessage());die;
throw new UsernameNotFoundException($e->getMessage());
}
}
When I call $response->toArray() or $response->getContent(), an exception is thrown and I get the following error message on Postman
<pre class='xdebug-var-dump' dir='ltr'>
<small>/var/www/html/backend/src/Security/Provider/KeycloakUserProvider.php:50:</small><small>string</small> <font color='#cc0000'>'HTTP/2 401 returned for "https://oauth_server/userinfo".'</font> <i>(length=127)</i>
</pre>
An example of the response received on the browser:
{"error":"invalid_request","error_description":"Token not provided"}
Why can't I access the response directly by calling $response->toArray()?
Whenever the status code of the response is not "good" (e.g. in the 300-599 range), the response is considered exceptional, and you are supposed to handle it.
This is clearly documented here:
When the HTTP status code of the response is in the 300-599 range (i.e. 3xx, 4xx or 5xx), the getHeaders(), getContent() and toArray() methods throw an appropriate exception, all of which implement the HttpExceptionInterface.
To opt-out from this exception and deal with 300-599 status codes on your own, pass false as the optional argument to every call of those methods, e.g. $response->getHeaders(false);.
If you do not want the client to throw an exception when encountering a non-OK response, you need to pass false to getContent() or toArray().
E.g.
$rawResponse = $response->getContents(false);
$arrayResponse = $response->toArray(false);
There is nothing wrong in handling the exception explicitly in your code, and will make your application better express the conditions it encounters. A "non-good" should be treated as anomalous, and handled accordingly.

is that possible sending http request from lumen using guzzlehttp?

actually i want to validate given token .. the validate code written in another lumen package. i have got some issues when i send request to validate token. i dont know why it's not working. cant use another api inside lumen ?
if i use that check token api in postman https://i.stack.imgur.com/kSpJt.png. it works fine. it's thrown error when i call that api inside other lumen package
this is what i got when use this api in postman https://i.stack.imgur.com/hfFzk.png
error log https://i.stack.imgur.com/ds0oR.png
<?php
namespace App\Helpers;
use App\Helpers\ResponseBuilder;
class check_customer_token_verification
{
public static function check($token, $vendor_id)
{
$client = new \GuzzleHttp\Client();
$result = $client->post('dev.adiswar-crm.local/customer/crm/v-1-0-0/check-token', [
'form_params' => [
'token' => isset($token)?$token:'',
'vendor_id' => $vendor_id,
]
]);
$res_data = json_decode($result->getBody()->getContents()); dd($res_data);
if ($res_data->http_code == 401) {
return ResponseBuilder::responseResult(400, $res_data->message);
}
return $res_data;
}
} ```
dump this api in postman. i got issue which is below
^ {#120
+"http_code": 400
+"message": """
Server error: `POST dev.adiswar-crm.local/customer/crm/v-1-0-0/check-token` resulted in a `500 Internal Server Error` response:
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex,nofollow" />
<style>
(truncated...)
"""
}```
You need to define your form_params, though your code can work but I would also suggest using try catch blocks and adding your 401 exception in catch block (& other 400 in there), see the changes I have made
public static function check($token, $vendor_id)
{
try{
$client = new \GuzzleHttp\Client();
define("form_params", \GuzzleHttp\RequestOptions::FORM_PARAMS );
$guzzleResponse = $client->post('dev.adiswar-crm.local/customer/crm/v-1-0-0/check-token', [
'form_params' => [
'token' => isset($token) && !empty($token) ? $token : '',
'vendor_id' => $vendor_id,
]
]);
if ($guzzleResponse->getStatusCode() == 200) {
$result = json_decode($guzzleResponse->getBody(),true);
// dd($result);
}
return $result;
}catch(\GuzzleHttp\Exception\RequestException $e){
// Catch all 4XX errors
dd($e->getMessage, $e->getTraceAsString());
// To catch exactly error 401 use
if ($e->hasResponse()){
if ($e->getResponse()->getStatusCode() == '401') {
return ResponseBuilder::responseResult(400, $e->getMessage());
}
}
}catch(Exception $e){
//other errors
}
}

ServerException in RequestException.php line 107: 500 Internal Server Error

I am using laravel framework.
I am trying to update an existing data using api (kinda new to this).
So this is my route
Route::group(['middleware' => 'web'], function () {
Route::post('/update_supplier_details/{id}', "UpdateController#update_supplier_details");
});
This is my Controller
public function update_supplier_details(Request $request, $id){
$details = $request->all();
$client = new CharmeAPI;
$token = Session::get('token');
$url = "https://api.charmeapp.com/api/v1/suppliers/{$id}?token={$token}";
$response = $client->request('POST', $url,['form_params' => $details])->getBody();
echo $response;
$data = json_decode($response, true);
$status = array_get($data, 'status');
$message = array_get($data, 'error.msg');
if($status == 'error'){
session(['update_supplier_details_error' => $status]);
return redirect()->back()->with('supplier_details_msg', $message);
}
else if($status == 'ok') {
session(['update_supplier_details_error' => $status]);
session(['supplier_details_first_name' => array_get($data, 'data.Supplier.first_name')]);
session(['supplier_details_last_name' => array_get($data, 'data.Supplier.last_name')]);
$first_name = session('supplier_details_first_name');
$last_name = session('supplier_details_last_name');
return $first_name.$last_name;
return redirect()->back()->with('supplier_details_msg', $first_name.' '.$last_name.' added successfully');
}
}
}
and I am getting this error -
ServerException in RequestException.php line 107:
Server error: POST https://api.charmeapp.com/api/v1/suppliers/139?token=Q8vJLPvpnRImoz5Li4tVfGtGliyGBQcx3NdqYbNdRaYYvsaoLncyDvFHkriS resulted in a 500 Internal Server Error response:
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex,nofollow" />
<style>
(truncated...)
But if I use postman to call the api url I get the desired data
Any help pls
Make sure you pass the correct parameters and token to the api.

POST request in laravel 5 with token via PhpUnit?

I am trying to test my Laravel APIs using phpunit and I am using the $this->call(); method to perform calls and see if they are working fine.
I am also JWT for authentication and hence have to pass my token with it. Simple GET requests are easy:
$response = $this->call('GET', 'users?token=' . $this->token);
But when I need to create a new user or any resource for that matter, I am trying to do:
$response = $this->call('POST', 'users/?token=' . $this->token, $user);
But it is giving me a redirect like so:
<!DOCTYPE html>\n
<html>\n
<head>\n
<meta charset="UTF-8" />\n
<meta http-equiv="refresh" content="1;url=http://localhost" />\n
\n
<title>Redirecting to http://localhost</title>\n
</head>\n
<body>\n
Redirecting to http://localhost.\n
</body>\n
</html>
Now when I did some digging, I came across this:
Redirect 302 on Laravel POST request
And the API for the call method looks like so:
$response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content);
So I tried this:
$response = $this->call('POST', 'users/?token=' . $this->token, $user, [], [], [], ['Content-Type' => 'application/x-www-form-urlencoded']);
But I am still getting a redirect. What am I missing?
Why don't try something like this?
$token = ‘your token’;
$method = ‘POST’;
$params = [];
$response = $this->call($method,'http://api.api.app/api/',
$params,[],[],['HTTP_Authorization' => 'Bearer ' . $token],[]);
$this->response = $response;
$this->seeStatusCode(200);
Update:
You have CORS enabled in Laravel? Maybe this is the reason.
Use the header: 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
Or try laravel-cors package.

guzzle `http_errors` changes error from 500 to 404

i have a function im testing which suppose to return error 500 but after adding 'http_errors' => 'false' to the put definition, the returned error changes from 500 to 404.
this is my function:
public function testApiAd_updateWithIllegalGroupId($adId)
{
$client = new Client(['base_uri' => self::$base_url]);
try {
$response = $client->put(self::$path.$adId, ['form_params' => [
'name' => 'bellow content - guzzle testing',
'description' => 'guzzle testing ad - demo',
'group_id' => '999999999',
]]);
} catch (Guzzle\Http\Exception\BadResponseException $e) {
//Here i want to compare received error to 500
}
}
right now this function will return server error: 500 but it also stops the class from executing rest of the tests and i can't assert it.
how can i use the guzzle getStatusCode() in my function while getting error 500 and not 404 as i mentioned above
The BadResponseException contains the original Request and the Response object. So you can, the catch block the following assertion:
} catch (Guzzle\Http\Exception\BadResponseException $e) {
//Here i want to compare received error to 500
$responseCode = $e->getResponse()->getStatusCode();
$this->assertEquals(500, $responseCode, "Server Error");
}
Further info in the doc

Categories