-
-
Notifications
You must be signed in to change notification settings - Fork 19
Ensure reports are json_encodable. (Fix silently failing reports with Malformed UTF8 in stacktrace) #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Ensure reports are json_encodable. (Fix silently failing reports with Malformed UTF8 in stacktrace) #42
Conversation
|
Just as a followup. It might be better if I just update |
|
I noticed the following issue in the phpstan workflow (71cae65) output: This is fixed in 3660995. Though brought up a typing caveat... As in the following method: /**
* @template K of array-key
*
* @param array<K,mixed> $input
* @return array<K,mixed>
*/
protected static function replaceNonEncodableEntries(array $input): array
{
foreach ($input as $key => $value) {
try {
json_encode($input[$key], JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
if (is_string($value)) {
$input[$key] = sprintf('[%s: CORRUPT DATA]: %d bytes | ERR: %s', self::REPLACED_ENTRY_PREFIX, strlen($value), $e->getMessage());
} elseif (is_array($value)) {
$input[$key] = self::replaceNonEncodableEntries($value);
} else {
$input[$key] = sprintf('[%s: NON ENCODABLE]: type %s', self::REPLACED_ENTRY_PREFIX, gettype($value));
}
}
}
return $input;
}
```
Should the value be anything other than a string, it would also become a string. Not sure if this arrises an issue? And my `else` statement on the replacement part should ensure the type of the value remains intact? |
|
Hi @YasserB94, Sorry for the late response to your PR we've been quite busy with the whole performance monitoring launch. While I like the idea, you're the first one to have this problem and think it is not that useful to spend computer cycles on making a JSON string from an array to throw it away again. So what I propose, is that we keep the sanitizer as is, add it to the CurlSender & GuzzleSender with an option to enable sanitizing the payload but disabled by default. That way we transform to JSON when we need it and immediately also do it for traces. Last question, does this happen a lot in Wordpress that you've got malformed UTF-8? Haven't had such an issue with Laravel in the last 7 years or so. Kind regards, Ruben |
|
Hey @rubenvanassche, No worries! I've been loving all the posts and updates from spatie the past weeks!😄 I like that you bring up the compute cycles on processing the json and going through the array. It itched the back of my mind as well. Thanks for pointing out a better spot to put this code as well, I wasn't sure where to put it all. Though on this code I figured, let's not get paralysed and just await a review. For your last question, nope it doesn't happen a lot. Exceptions and Errors are handled great by Flare. I have been unable to discover why raw binary data is added to the php files. It's somewhere on the bottom of my list of rabbit holes to dive into in this wonderful digital world I'll turn this PR into a draft and do my best at adding the changes above 😄 |
abb4431 to
10c51c1
Compare
- Added shared sanitization behaviour into an AbstractSender class - Injected the PayloadSanitizer here - Optionally call it in the prepare payload method when configured - Used the existing config array to take in the option - added the logic from ReportSanitizer into JsonEncodableSanitizer - Bound the sanitizer in the container
10c51c1 to
f15086a
Compare
|
I hope I understood you correctly and applied the changes in f15086a Changes made
Thoughts
|
Why?
Whilst creating a WordPress plugin to send exceptions to Flare. I noticed reports sent, when I invoked them from the wp-cli, they would silently fail.
In 1.0 I had a middleware that would just remove the whole stack trace to resolve this. I spoke to @rubenvanassche about this in a mail-thread a couple weeks ago.
After some digging, I noticed that an error would be thrown if I added
JSON_THROW_ON_ERRORto the ReportTrimmer here:flare-client-php/src/Truncation/ReportTrimmer.php
Lines 39 to 43 in 3c280c0
it would throw (
JsonException: Malformed UTF-8 characters, possibly incorrectly encoded),further down the road I noticed that, even should I pave the road for the report to reach the API. Either curl would fail, or the API wouldn't like it.
TLDR: Non UTF-8 characters, from binaries end up in the stack trace, silently making the report fail.
Changes in this PR
Disclaimer: I tried to do this right. Although I figured I'd just create a PR and iterate on feedback instead of spending years attempting to wrap some code with a golden bow.
I added a Support class that checks whether an array can be json_encoded. If it can't, it recurses through the whole payload. Replacing any entry that cannot be json_encoded.
For the replacement, I opted to add the error message, the amount of bytes omitted, and a Prefix so it's clear that this was replaced by the client internally
Additional Ideas/caveats
resourcewould be replaced by null injson_encode? Though now it would be replaced by a NON ENCODABLE message.Art
After adding these changes, I was able to successfully see my exception/report in flare.
