Skip to content

Conversation

@marklearst
Copy link
Owner

Add support for extracting error messages from text/plain and text/html responses, which can occur during gateway errors (502, 503) or when the API returns HTML error pages.

Problem:

  • When Figma API returned non-JSON errors (e.g., 502 Bad Gateway with HTML), users would only see generic error message with no debugging context
  • No visibility into actual error content for troubleshooting

Solution:

  • Check content-type header before parsing response body
  • For application/json: parse as JSON (existing behavior)
  • For text/plain or text/html: read body as text and use as error message
  • Truncate long responses (>200 chars) to prevent huge error messages
  • Gracefully handle empty bodies and parsing errors

Changes:

  • src/api/fetcher.ts: Added text/plain and text/html response handling
  • src/api/mutator.ts: Added text/plain and text/html response handling
  • tests/api/fetcher.test.ts: Added 7 tests for text error responses
  • tests/api/mutator.test.ts: Added 7 tests for text error responses

Test coverage: 100%

Refs: Codex Audit Item #6

Add support for extracting error messages from text/plain and text/html
responses, which can occur during gateway errors (502, 503) or when the
API returns HTML error pages.

Problem:
- When Figma API returned non-JSON errors (e.g., 502 Bad Gateway with HTML),
  users would only see generic error message with no debugging context
- No visibility into actual error content for troubleshooting

Solution:
- Check content-type header before parsing response body
- For application/json: parse as JSON (existing behavior)
- For text/plain or text/html: read body as text and use as error message
- Truncate long responses (>200 chars) to prevent huge error messages
- Gracefully handle empty bodies and parsing errors

Changes:
- src/api/fetcher.ts: Added text/plain and text/html response handling
- src/api/mutator.ts: Added text/plain and text/html response handling
- tests/api/fetcher.test.ts: Added 7 tests for text error responses
- tests/api/mutator.test.ts: Added 7 tests for text error responses

Test coverage: 100%

Refs: Codex Audit Item #6
Copilot AI review requested due to automatic review settings December 30, 2025 00:20
@codecov
Copy link

codecov bot commented Dec 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.73%. Comparing base (c96a36e) to head (2dc629d).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #12      +/-   ##
==========================================
+ Coverage   90.47%   90.73%   +0.25%     
==========================================
  Files          34       34              
  Lines         903      917      +14     
  Branches      246      256      +10     
==========================================
+ Hits          817      832      +15     
+ Misses         85       84       -1     
  Partials        1        1              
Flag Coverage Δ
unittests 90.73% <100.00%> (+0.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@marklearst marklearst merged commit 974a824 into main Dec 30, 2025
8 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves error parsing for non-JSON API responses by adding support for text/plain and text/html content types, which commonly occur during gateway errors (502, 503) or when APIs return HTML error pages.

Key changes:

  • Enhanced error message extraction to handle text/plain and text/html responses in addition to JSON
  • Added truncation logic (200 characters) for long error responses to prevent unwieldy error messages
  • Comprehensive test coverage for new error handling scenarios including empty bodies and parsing failures

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/api/fetcher.ts Added text/plain and text/html error response handling with truncation logic
src/api/mutator.ts Added text/plain and text/html error response handling with truncation logic
tests/api/fetcher.test.ts Added 7 test cases covering text error responses, truncation, empty bodies, null content-type, and parsing errors
tests/api/mutator.test.ts Added 7 test cases covering text error responses, truncation, empty bodies, null content-type, and parsing errors

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +431 to +437
try {
await fetcher(DUMMY_URL, DUMMY_TOKEN)
} catch (err) {
expect((err as Error).message).toHaveLength(203) // 200 chars + "..."
expect((err as Error).message.endsWith('...')).toBe(true)
}
})
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

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

The truncation test uses a try-catch block but doesn't verify that an error was actually thrown. If the function call unexpectedly succeeds, the test would pass without any assertions being executed. Add an assertion to ensure an error was thrown, such as expect.fail('Should have thrown') before the catch block or use expect.assertions(2) at the start of the test.

Copilot uses AI. Check for mistakes.
Comment on lines +214 to +220
try {
await mutator(url, token, 'CREATE', body)
} catch (err) {
expect((err as Error).message).toHaveLength(203) // 200 chars + "..."
expect((err as Error).message.endsWith('...')).toBe(true)
}
})
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

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

The truncation test uses a try-catch block but doesn't verify that an error was actually thrown. If the function call unexpectedly succeeds, the test would pass without any assertions being executed. Add an assertion to ensure an error was thrown, such as expect.fail('Should have thrown') before the catch block or use expect.assertions(2) at the start of the test.

Copilot uses AI. Check for mistakes.
Comment on lines +162 to +175
} else if (
contentType.includes('text/plain') ||
contentType.includes('text/html')
) {
// For text responses (e.g., 502 Bad Gateway), use the body text
const textBody = await response.text()
if (textBody) {
// Truncate long HTML/text responses to a reasonable length
const maxLength = 200
errorMessage =
textBody.length > maxLength
? `${textBody.slice(0, maxLength)}...`
: textBody
}
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

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

The error message extraction logic for text/plain and text/html responses is duplicated between fetcher.ts and mutator.ts (including the 200-character truncation logic). Consider extracting this into a shared utility function to reduce duplication and improve maintainability. This would make it easier to adjust the truncation length or error handling logic in the future without needing to update both files.

Copilot uses AI. Check for mistakes.
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.

1 participant