Skip to content

Conversation

Moumouls
Copy link
Member

@Moumouls Moumouls commented Oct 15, 2025

Pull Request

Issue

Parse SDK V7 introduce a regression about 500 errors. The issue was introduced in #2503.

Approach

Fix to so that server 500 responses are returned in same format as pre v7 release. Even though this is technically a breaking change compared to Parse JS SDK 7.0.0, we don't release it as such, as it is a correction of the accidental breaking change released in 7.0.0.

Copy link

parse-github-assistant bot commented Oct 15, 2025

🚀 Thanks for opening this pull request!

Copy link

coderabbitai bot commented Oct 15, 2025

📝 Walkthrough

Walkthrough

Updates RESTController’s retry-failure handling to parse and reject with JSON error objects when retries exhaust on 5xx responses. Tests updated: one test now validates error shape; a new test covers consecutive 5xx errors and verifies code/message propagation.

Changes

Cohort / File(s) Summary
REST error handling
src/RESTController.ts
On exhausting retries for 5xx/non-connection errors, parse response.json() and reject with the parsed error object instead of the raw response.
Tests for error shape and 5xx flow
src/__tests__/RESTController-test.js
Expanded “abort-after-too-many-failures” test to assert code and error properties on thrown error. Added test for consecutive 5xx errors ensuring server-provided code and message are surfaced.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant RC as RESTController
  participant F as fetch()
  participant S as Server

  C->>RC: request(options)
  loop Retry on failure
    RC->>F: fetch(url, opts)
    F->>S: HTTP request
    S-->>F: Response (5xx or error)
    alt Connection error or 5xx
      RC->>RC: increment retries
      RC-->>C: retry (if below limit)
    else Success (2xx)
      F-->>RC: Response OK
      RC-->>C: Resolve(data)
    end
  end

  rect rgba(255, 235, 205, 0.35)
  note over RC: Retries exhausted
  RC->>F: last response available
  alt Non-connection 5xx response
    RC->>F: response.json()
    F-->>RC: { code, message, ... }
    RC-->>C: Reject(parsed error object)
  else Connection error
    RC-->>C: Reject(connection error)
  end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description includes the standard header and an Approach section but omits the required “Closes:” line under Issue and entirely omits the Tasks checklist, so it does not fully conform to the repository’s description template. Please add a “Closes: ” line under the Issue section to link the relevant issue and include the Tasks section with the checklist items for adding tests and documentation as specified by the template.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title succinctly and specifically describes the main fix by indicating that the error format for 5xx server responses was incorrect. It directly reflects the changes in the pull request where the code now parses the server response body and returns a properly formatted error object. As a concise, clear summary it enables easy understanding of the patch’s intent.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parseplatformorg
Copy link
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Copy link

codecov bot commented Oct 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.88%. Comparing base (7bec0fd) to head (71db04b).
⚠️ Report is 2 commits behind head on alpha.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha    #2755   +/-   ##
=======================================
  Coverage   99.88%   99.88%           
=======================================
  Files          64       64           
  Lines        6219     6220    +1     
  Branches     1472     1488   +16     
=======================================
+ Hits         6212     6213    +1     
  Misses          7        7           

☔ 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/RESTController.ts (1)

217-218: LGTM! Improved error handling for exhausted 5xx retries.

Parsing the response as JSON before rejection makes 5xx error handling consistent with 4xx errors (lines 196-198) and ensures the error object has the expected shape (code, error/message properties) for handleError to transform it into a ParseError.

Optional: Consider handling malformed JSON responses.

If the server returns a 5xx error with invalid JSON, response.json() will throw and be caught by the outer catch block (line 223), but the resulting error may not have the expected shape. While this is acceptable (the application won't crash), you could optionally add explicit handling:

 } else {
   // After the retry limit is reached, fail
-  const error = await response.json();
-  promise.reject(error);
+  try {
+    const error = await response.json();
+    promise.reject(error);
+  } catch (parseError) {
+    promise.reject({
+      code: ParseError.INTERNAL_SERVER_ERROR,
+      error: `Server error (status ${status})`,
+    });
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bec0fd and 71db04b.

📒 Files selected for processing (2)
  • src/RESTController.ts (1 hunks)
  • src/__tests__/RESTController-test.js (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/__tests__/RESTController-test.js (1)
src/CoreManager.ts (1)
  • RESTController (135-145)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 20, 20.15.1)
  • GitHub Check: build (Node 22, 22.4.1)
  • GitHub Check: build (Node 18, 18.20.4)
🔇 Additional comments (2)
src/__tests__/RESTController-test.js (2)

87-101: LGTM! Test properly validates error object shape.

The updated test now correctly:

  • Expects 3 assertions (line 87)
  • Mocks all 5xx responses with proper JSON bodies containing code and error fields (lines 89-93)
  • Validates that fetchError.code and fetchError.error are present and correct (lines 100-101)

This ensures the error object returned by ajax() has the expected structure when retries are exhausted.


183-198: LGTM! Good test coverage for 5xx error propagation through the request pipeline.

This test verifies that 5xx errors, after exhausting retries, properly propagate through request()handleError()ParseError. The test correctly validates:

  • error.code is preserved (line 195)
  • error.message contains the server error message (line 196)

Note: The test uses error.message (not error.error) because handleError transforms the raw error object into a ParseError instance, which stores the error field as its message property.

@mtrezza
Copy link
Member

mtrezza commented Oct 15, 2025

@coderabbitai is this a breaking change? Suggest a an angular commit message as PR title.

Copy link

coderabbitai bot commented Oct 15, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the diff for RESTController.ts to see the actual changes
git diff origin/alpha...HEAD -- src/RESTController.ts

# Also check if there are any other files that might be affected
git diff origin/alpha...HEAD --name-only

Length of output: 583


@mtrezza: Yes, this is a breaking change.

Breaking Change Analysis

The PR changes the error rejection format for 5xx errors (after retry limit is reached):

  • Before: Rejected with Response object
  • After: Rejects with parsed JSON object (e.g., { code: 500, error: "..." })

This breaks any existing error handling code that expects a Response object and accesses methods like .status, .json(), .headers, etc.

Example of breaking code:

try {
  await Parse.Cloud.run("someFunction");
} catch (error) {
  // This will now fail - error is no longer a Response object
  const status = error.status;
  const body = await error.json();
}

Suggested Angular Commit Messages

With breaking change indicator:

fix!: return parsed error objects for 5xx responses after retry limit

BREAKING CHANGE: RESTController now returns parsed JSON error objects instead of raw Response objects when 5xx errors occur after exhausting retries. Update error handling code to expect objects with `code` and `error` properties instead of Response objects.

Alternative (shorter):

fix(rest)!: parse 5xx error responses as JSON objects

Note: The ! after the type indicates a breaking change in Angular commit convention. You should also include a BREAKING CHANGE: footer in the commit body to explain the impact and migration path.

@mtrezza
Copy link
Member

mtrezza commented Oct 15, 2025

@Moumouls What's the story behind this issue here? Why do we need this fix?

@mtrezza mtrezza changed the title fix: 500 error handling fix: Returned error on 5xx responses after retry limit has incorrect format Oct 15, 2025
@mtrezza mtrezza changed the title fix: Returned error on 5xx responses after retry limit has incorrect format fix: Returned error for 5xx server responses have incorrect format Oct 15, 2025
@mtrezza mtrezza changed the title fix: Returned error for 5xx server responses have incorrect format fix: Returned error for 5xx server response has incorrect format Oct 15, 2025
@mtrezza mtrezza merged commit 16a34d9 into parse-community:alpha Oct 15, 2025
13 checks passed
parseplatformorg pushed a commit that referenced this pull request Oct 15, 2025
## [7.0.1-alpha.1](7.0.0...7.0.1-alpha.1) (2025-10-15)

### Bug Fixes

* Returned error for 5xx server response has incorrect format ([#2755](#2755)) ([16a34d9](16a34d9))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 7.0.1-alpha.1

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Oct 15, 2025
parseplatformorg pushed a commit that referenced this pull request Oct 15, 2025
## [7.0.1](7.0.0...7.0.1) (2025-10-15)

### Bug Fixes

* Returned error for 5xx server response has incorrect format ([#2755](#2755)) ([16a34d9](16a34d9))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 7.0.1

@parseplatformorg parseplatformorg added the state:released Released as stable version label Oct 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:released Released as stable version state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants