17

i have this entry in my laravel 5.3 log

2016-12-22 17:23:37] local.ERROR: GuzzleHttp\Exception\ClientException: Client error: POST https://api.sparkpost.com/api/v1/transmissions resulted in a 400 Bad Request response: { "errors": [ { "message": "Message generation rejected", "description": "recipient address suppressed due to customer p (truncated...)

why does it truncate an important error message? now i cannot figure out what is going wrong...

Toskan
  • 13,911
  • 14
  • 95
  • 185

6 Answers6

22

Because your request throws a Guzzle Exception, as a workaround, instead of calling $e->getMessage(), You can simply try:

$e->getResponse()->getBody()->getContents();

If you don't want to modify the report() method.

Worked nice for me.

Arda
  • 6,756
  • 3
  • 47
  • 67
  • 2
    This solution should be the accepted answer. Nice and simple. – mp035 Apr 01 '20 at 03:59
  • im accepting this answer without verifying if it actually works... hope it does. Cheers – Toskan May 11 '20 at 19:23
  • @Toskan Where are you supposed to do this? Your question was about the error in the log file. If you want to fix that, you either need to modify the report method, as shown in my answer (which uses the above code to get the contents of the message), or hotfix guzzle like your answer. – patricus May 13 '20 at 14:17
14

The truncating is done by the Guzzle library. It only shows the first 120 characters of the response. I am assuming this is because responses could potentially be very long.

If you would like to see the full message, you should be able to customize how guzzle exceptions are handled.

Update the report() method in your app/Exceptions/Handler.php to something like:

public function report(Exception $exception)
{
    // this is from the parent method
    if ($this->shouldntReport($exception)) {
        return;
    }

    // this is from the parent method
    try {
        $logger = $this->container->make(\Psr\Log\LoggerInterface::class);
    } catch (Exception $ex) {
        throw $exception; // throw the original exception
    }

    // this is the new custom handling of guzzle exceptions
    if ($exception instanceof \GuzzleHttp\Exception\RequestException) {
        // get the full text of the exception (including stack trace),
        // and replace the original message (possibly truncated),
        // with the full text of the entire response body.
        $message = str_replace(
            rtrim($exception->getMessage()),
            (string) $exception->getResponse()->getBody(),
            (string) $exception
        );

        // log your new custom guzzle error message
        return $logger->error($message);
    }

    // make sure to still log non-guzzle exceptions
    $logger->error($exception);
}

Note: this is done in the report method, so it only affects what is written to the log. If the exception is dumped to the terminal or to the browser, it will still show the truncated message.

patricus
  • 59,488
  • 15
  • 143
  • 145
  • i did some adjustments... problem is is that $message = (string) $e does contain the stacktrace. substr($msg, 0, -135) will not work thus. To read the result one has now to read at the VERY BOTTOM of the error message, at the bottom of the stacktrace actually – Toskan Mar 09 '17 at 15:08
  • 1
    @Toskan You were correct, and the original implementation was not correct (as I had noted, it was untested). I have corrected the code, and actually tested it so it should work as is. I also changed it so that it will continue to include the stack trace, whereas the original algorithm had been designed so that only the message would be logged without the stack trace. – patricus Mar 09 '17 at 18:44
  • how to handle same in laravel 4.1 – Parvez Alam Dec 20 '18 at 05:09
  • This doesn't work for me. The second if statement isn't true so it doesn't run. – Martijn Hiemstra May 14 '20 at 08:25
  • @MartijnHiemstra That's on purpose. You only want that extra code to run when you're handling a `\GuzzleHttp\Exception\RequestException`. – patricus May 14 '20 at 15:59
12

as alternative solution:

hotfix RequestException.php

ta_integration/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php

replace

$size = $body->getSize();
$summary = $body->read(120);
$body->rewind();

if ($size > 120) {

with for example:

    $size = $body->getSize();
    $summary = $body->read(999);
    $body->rewind();

    if ($size > 999) {

function

getResponseBodySummary

Toskan
  • 13,911
  • 14
  • 95
  • 185
  • 2
    This is not recommended. If you modify the code inside the vendor directory, your change will be lost the next time you do a `composer update`. – patricus Mar 09 '17 at 18:46
  • 11
    i am totally aware of that, furthermore it applies only when said library gets updated, not on each composer update. But it helps the programmer figure out what is the original error about, fix the issue, and move on. – Toskan Mar 09 '17 at 20:38
  • In the current versions, this setting is set in `vendor/guzzlehttp/psr7/src/Message.php`, method `bodySummary`, parameter `truncateAt`. – Umair Ahmed Aug 24 '23 at 11:04
3

Edit vendor/guzzlehttp/psr7/src/Message.php

public static function bodySummary(MessageInterface $message, $truncateAt = 999)

Edit vendor/guzzlehttp/psr7/src/functions.php

function get_message_body_summary(MessageInterface $message, $truncateAt = 999)
hacknull
  • 317
  • 1
  • 5
2

None of these solutions here helped me. I found a solution here that helped. By the user sidk2020. Here is his solution in case the link breaks:

I did something very adventurous. I modified guzzel's exception handler

guzzel on purpose only reads up 120 bytes of info and prints truncated next to it.

The file is located at : /vendor/guzzlehttp/guzzle/src/Exception/RequestException.php

So I modified that function and below is what my function looks like:

public static function getResponseBodySummary(ResponseInterface $response) { 
    $body = $response->getBody();

    if (!$body->isSeekable() || !$body->isReadable()) {
        return null;
    }

    $size = $body->getSize();

    if ($size === 0) {
        return null;
    }

    // Matches any printable character, including unicode characters:
    // letters, marks, numbers, punctuation, spacing, and separators.
    if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $body)) {
        return null;
    }

    return $body;

}
Community
  • 1
  • 1
Noah Gary
  • 916
  • 12
  • 25
1

In vendor/guzzlehttp/psr7/src/functions.php

there's this function:

function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
{
    return Message::bodySummary($message, $truncateAt);
}

just change the $truncateAt = 120 to whatever you are confortable with

user1738671
  • 77
  • 1
  • 8