Skip to content

Commit 2033e4a

Browse files
[12.x] Allow setting the RequestException truncation limit per request (#55897)
* set a per-request truncation * simplify * revert send changes, move to Response@toException * apply CI * test async * formatting * fix wording * Update PendingRequest.php * Update Response.php --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent 5474458 commit 2033e4a

File tree

3 files changed

+161
-2
lines changed

3 files changed

+161
-2
lines changed

src/Illuminate/Http/Client/PendingRequest.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ class PendingRequest
214214
'query',
215215
];
216216

217+
/**
218+
* The length at which request exceptions will be truncated.
219+
*
220+
* @var int<1, max>|false|null
221+
*/
222+
protected $truncateExceptionsAt = null;
223+
217224
/**
218225
* Create a new HTTP Client instance.
219226
*
@@ -1429,7 +1436,15 @@ public function mergeOptions(...$options)
14291436
*/
14301437
protected function newResponse($response)
14311438
{
1432-
return new Response($response);
1439+
return tap(new Response($response), function (Response $laravelResponse) {
1440+
if ($this->truncateExceptionsAt === null) {
1441+
return;
1442+
}
1443+
1444+
$this->truncateExceptionsAt === false
1445+
? $laravelResponse->dontTruncateExceptions()
1446+
: $laravelResponse->truncateExceptionsAt($this->truncateExceptionsAt);
1447+
});
14331448
}
14341449

14351450
/**
@@ -1522,6 +1537,31 @@ protected function dispatchConnectionFailedEvent(Request $request, ConnectionExc
15221537
}
15231538
}
15241539

1540+
/**
1541+
* Indicate that request exceptions should be truncated to the given length.
1542+
*
1543+
* @param int<1, max> $length
1544+
* @return $this
1545+
*/
1546+
public function truncateExceptionsAt(int $length)
1547+
{
1548+
$this->truncateExceptionsAt = $length;
1549+
1550+
return $this;
1551+
}
1552+
1553+
/**
1554+
* Indicate that request exceptions should not be truncated.
1555+
*
1556+
* @return $this
1557+
*/
1558+
public function dontTruncateExceptions()
1559+
{
1560+
$this->truncateExceptionsAt = false;
1561+
1562+
return $this;
1563+
}
1564+
15251565
/**
15261566
* Handle the given connection exception.
15271567
*

src/Illuminate/Http/Client/Response.php

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ class Response implements ArrayAccess, Stringable
4747
*/
4848
public $transferStats;
4949

50+
/**
51+
* The length at which request exceptions will be truncated.
52+
*
53+
* @var int<1, max>|false|null
54+
*/
55+
protected $truncateExceptionsAt = null;
56+
5057
/**
5158
* Create a new response instance.
5259
*
@@ -297,7 +304,19 @@ public function toPsrResponse()
297304
public function toException()
298305
{
299306
if ($this->failed()) {
300-
return new RequestException($this);
307+
$originalTruncateAt = RequestException::$truncateAt;
308+
309+
try {
310+
if ($this->truncateExceptionsAt !== null) {
311+
$this->truncateExceptionsAt === false
312+
? RequestException::dontTruncate()
313+
: RequestException::truncateAt($this->truncateExceptionsAt);
314+
}
315+
316+
return new RequestException($this);
317+
} finally {
318+
RequestException::$truncateAt = $originalTruncateAt;
319+
}
301320
}
302321
}
303322

@@ -395,6 +414,31 @@ public function throwIfServerError()
395414
return $this->serverError() ? $this->throw() : $this;
396415
}
397416

417+
/**
418+
* Indicate that request exceptions should be truncated to the given length.
419+
*
420+
* @param int<1, max> $length
421+
* @return $this
422+
*/
423+
public function truncateExceptionsAt(int $length)
424+
{
425+
$this->truncateExceptionsAt = $length;
426+
427+
return $this;
428+
}
429+
430+
/**
431+
* Indicate that request exceptions should not be truncated.
432+
*
433+
* @return $this
434+
*/
435+
public function dontTruncateExceptions()
436+
{
437+
$this->truncateExceptionsAt = false;
438+
439+
return $this;
440+
}
441+
398442
/**
399443
* Dump the content from the response.
400444
*

tests/Http/HttpClientTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,81 @@ public function testRequestExceptionWithCustomTruncatedSummary()
13061306
throw new RequestException(new Response($response));
13071307
}
13081308

1309+
public function testRequestLevelTruncationLevelOnRequestException()
1310+
{
1311+
RequestException::truncateAt(60);
1312+
1313+
$this->factory->fake([
1314+
'*' => $this->factory->response(['error'], 403),
1315+
]);
1316+
1317+
$exception = null;
1318+
try {
1319+
$this->factory->throw()->truncateExceptionsAt(3)->get('http://foo.com/json');
1320+
} catch (RequestException $e) {
1321+
$exception = $e;
1322+
}
1323+
1324+
$this->assertEquals("HTTP request returned status code 403:\n[\"e (truncated...)\n", $exception->getMessage());
1325+
1326+
$this->assertEquals(60, RequestException::$truncateAt);
1327+
}
1328+
1329+
public function testNoTruncationOnRequestLevel()
1330+
{
1331+
RequestException::truncateAt(60);
1332+
1333+
$this->factory->fake([
1334+
'*' => $this->factory->response(['error'], 403),
1335+
]);
1336+
1337+
$exception = null;
1338+
1339+
try {
1340+
$this->factory->throw()->dontTruncateExceptions()->get('http://foo.com/json');
1341+
} catch (RequestException $e) {
1342+
$exception = $e;
1343+
}
1344+
1345+
$this->assertEquals("HTTP request returned status code 403:\nHTTP/1.1 403 Forbidden\r\nContent-Type: application/json\r\n\r\n[\"error\"]\n", $exception->getMessage());
1346+
1347+
$this->assertEquals(60, RequestException::$truncateAt);
1348+
}
1349+
1350+
public function testRequestExceptionDoesNotTruncateButRequestDoes()
1351+
{
1352+
RequestException::dontTruncate();
1353+
1354+
$this->factory->fake([
1355+
'*' => $this->factory->response(['error'], 403),
1356+
]);
1357+
1358+
$exception = null;
1359+
try {
1360+
$this->factory->throw()->truncateExceptionsAt(3)->get('http://foo.com/json');
1361+
} catch (RequestException $e) {
1362+
$exception = $e;
1363+
}
1364+
1365+
$this->assertEquals("HTTP request returned status code 403:\n[\"e (truncated...)\n", $exception->getMessage());
1366+
1367+
$this->assertFalse(RequestException::$truncateAt);
1368+
}
1369+
1370+
public function testAsyncRequestExceptionsRespectRequestTruncation()
1371+
{
1372+
RequestException::dontTruncate();
1373+
$this->factory->fake([
1374+
'*' => $this->factory->response(['error'], 403),
1375+
]);
1376+
1377+
$exception = $this->factory->async()->throw()->truncateExceptionsAt(4)->get('http://foo.com/json')->wait();
1378+
1379+
$this->assertInstanceOf(RequestException::class, $exception);
1380+
$this->assertEquals("HTTP request returned status code 403:\n[\"er (truncated...)\n", $exception->getMessage());
1381+
$this->assertFalse(RequestException::$truncateAt);
1382+
}
1383+
13091384
public function testRequestExceptionEmptyBody()
13101385
{
13111386
$this->expectException(RequestException::class);

0 commit comments

Comments
 (0)