-1

I am trying to customise the error responses in a Symfony app (6.0). The app makes as request using http client to an external API using an oauth token exchange. If the token is not valid the API gives a 401 response

    protected function request(string $token, string $url, array $query): array
    {
        //Create a new client
        $httpClient = HttpClient::create(['base_uri' => self::API_URL]);
        //Set up request headers
        $headers = [
            'Authorization' => 'Bearer ' . $token,
            'Content-type' => 'application/json'
        ];
        //Get response
        $response = $httpClient->request('GET', $url, [
            'headers' => $headers,
            'query' => $query,
        ]);
        //Return the body of the response object as an array
        return $response->toArray();
    }

When is test this with an invalid token it causes an exception to be thrown of type ClientException and this gives a HTTP 500 Internal Server Error with the message:

HTTP/2 401 returned for "https://www.strava.com/api/v3/athlete".

I was hoping to catch this error and display information on how to fix it using the methods described on https://symfony.com/doc/current/controller/error_pages.html. I thought that as it was a 401 error I could catch it in a page called error401.html.twig.

My question is why is this error treated as a 500 rather than a 401?

yivi
  • 42,438
  • 18
  • 116
  • 138
MartynW
  • 641
  • 2
  • 7
  • 23
  • 4
    GET requests have no request body and therefore do not need a content-type header. Why does everyone do this? – Phil Jan 18 '22 at 23:04

1 Answers1

2

You are reflecting back exactly what your http client is receiving. You should check the response code and return what you need for your site response rather than just regurgitating all the data from the client response.

$statusCode = $response->getStatusCode();
if (401 === $statusCode) {
    // set your response as desired
    
}
if (200 === $statusCode) {
    // set your response as desired
}

By default, if the client response is in the 3xx-5xx range, and you call getHeaders, getContent or toArray (as you were doing) then an HTTPExceptionInterface exception gets thrown. You can choose to try and catch that exception, or alternatively, you can still call those methods by passing an optional false value as a parameter.

$clientResponseData = $response->toArray(false);
gview
  • 14,876
  • 3
  • 46
  • 51
  • Looking at the docs I read: 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 - is the clientexception part of this? – MartynW Jan 18 '22 at 23:26
  • I updated my answer to address your additional question. With that said, I still believe the better solution is to handle client responses proactively, although it also is true that there are many other client exceptions that can occur, and bullet proofing your api for those exceptions is always a good idea. – gview Jan 19 '22 at 00:17