Skip to content

fix(middleware): log responses that are not JSON - #48

Merged
jfrosorio merged 2 commits into
v2from
fix-46
Oct 10, 2026
Merged

jfrosorio merged 2 commits into
v2from
fix-46

Conversation

@jfrosorio

Copy link
Copy Markdown
Contributor

Closes #46.

Backport of #45 to the 2.x line. Requests whose response body did not decode to a non-null JSON value were never logged: null was written to the non-nullable response_data column and the insert failed. This hit HTML error pages (a 403/404 for an Accept: */* client), empty 204 bodies, and streamed and file responses.

LogApiRequest now stores a JSON array redacted as before, any other non-null JSON value as is, and any other body as a string with invalid UTF-8 scrubbed so the json cast cannot fail on it. Streamed and file responses, which have no content to read, are stored as an empty string. No schema change. Written to stay compatible with PHP 7.2.

The README now states that key redaction applies to JSON responses only. Feature tests cover an HTML response, a 204, a streamed response and a body that is not valid UTF-8.

Copilot AI balanced review requested due to automatic review settings October 10, 2026 14:48
@jfrosorio jfrosorio self-assigned this Oct 10, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The fix is small and correctly resolves the non-nullable json column insert failure, with new tests covering each non-JSON case and CI provisioning mbstring across the PHP matrix that exercises mb_scrub.

0 open findings

What changed in this PR

This PR backports the fix from #45 (3.x) to the 2.x line, closing #46. Previously, the middleware did json_decode($content, true) and stored the result directly into the non-nullable json-cast response_data column. For any response that wasn't a JSON array/object (HTML error pages, empty 204 bodies, streamed/file responses, non-UTF-8 bodies), the decoded value was null, and writing null into the non-nullable column made the insert fail, so those requests were silently never logged. The new responseData() helper normalizes the body so a valid, non-null value is always stored.

Changes:

  • Extracted response-body handling into a private responseData() method that stores: '' for responses without string content (streamed/file), a redacted array for JSON objects/arrays, a non-null decoded JSON scalar as-is, and otherwise the raw body with invalid UTF-8 scrubbed via mb_scrub.
  • Added feature tests for HTML (403), 204 no-content, streamed, and non-UTF-8 responses, plus supporting routes in TestCase.
  • Documented in the README that key redaction applies to JSON responses only; non-JSON responses are stored as their raw body, unredacted.
File Description
src/​Http/​Middleware/​LogApiRequest.php Adds responseData() to safely normalize any response body into a non-null, UTF-8-safe value before storage.
tests/​TestCase.php Adds forbidden, no-content, streamed, and binary routes to exercise the new behavior.
tests/​Feature/​LogApiRequestMiddlewareTest.php Adds four feature tests covering HTML, 204, streamed, and non-UTF-8 responses.
README.md Clarifies that redaction applies only to JSON responses; non-JSON bodies are stored raw and unredacted.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@jfrosorio
jfrosorio merged commit af56999 into v2 Oct 10, 2026
9 checks passed
@jfrosorio
jfrosorio deleted the fix-46 branch October 10, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants