Skip to content

Conversation

@maratal
Copy link
Collaborator

@maratal maratal commented Oct 31, 2025

Addresses #2135

Summary by CodeRabbit

  • Bug Fixes

    • Error decoding now respects HTTP status codes, handles error payloads that are strings or objects, and supplies sensible default messages when fields are missing.
  • Tests

    • Added tests verifying decoding for minimal and full nested error payloads (duplicated copies present).
  • Test Utilities

    • Enhanced HTTP error simulator to support custom status codes, optional payload data, and reusable simulators.
  • Chores

    • Public encoder error-decoding API updated to accept an explicit status code parameter.

@coderabbitai
Copy link

coderabbitai bot commented Oct 31, 2025

Walkthrough

Adds a statusCode parameter to ARTEncoder.decodeErrorInfo, updates ARTJsonLikeEncoder to decode error payloads as dictionary or other types with explicit fallbacks using statusCode, propagates statusCode through ARTRest callers, extends test utilities to simulate status-coded payloads, and adds unit tests (duplicated) validating these cases.

Changes

Cohort / File(s) Summary
Protocol Definition
Source/PrivateHeaders/Ably/ARTEncoder.h
Added statusCode:(NSInteger)statusCode parameter to - (nullable ARTErrorInfo *)decodeErrorInfo:... in the ARTEncoder protocol.
Encoder Implementation
Source/ARTJsonLikeEncoder.m
Method signature changed to decodeErrorInfo:statusCode:error:; decode now distinguishes NSDictionary vs non-dictionary payloads, extracts code, status and message with fallbacks (code → statusCode * 100, status → statusCode, message → provided or default HTTP message), and returns ARTErrorInfo in all branches.
Call Sites / REST
Source/ARTRest.m
Updated calls to pass response.statusCode into decodeErrorInfo:statusCode:error:; minor formatting/rewrap of artificial error creation only.
Test Utilities
Test/AblyTests/Test Utilities/TestUtilities.swift
Added explicit stubData to ErrorSimulator, new initializers accepting stubData/stubDataDict, dictionary→Data helper, simulateIncomingServerErrorOnNextRequest overloads with optional statusCode and payload data, and added Ably-specific response headers in stubs.
Unit Tests
Test/AblyTests/Tests/UtilitiesTests.swift
Added tests verifying decoding when error is a string and when error is an object; note: each new test appears duplicated in the file.

Sequence Diagram(s)

sequenceDiagram
    participant REST as ARTRest
    participant Encoder as ARTJsonLikeEncoder
    participant ARTError as ARTErrorInfo

    REST->>Encoder: decodeErrorInfo(data, statusCode, &error)
    alt payload is NSDictionary
        Encoder->>Encoder: read error field (dict or other)
        Encoder->>Encoder: code = error[@"code"] ?? statusCode*100
        Encoder->>Encoder: status = error[@"statusCode"] ?? statusCode
        Encoder->>Encoder: message = error[@"message"] ?? defaultHTTPMessage
        Encoder->>ARTError: create(code,status,message)
        Encoder-->>REST: return ARTErrorInfo
    else payload is non-dictionary
        Encoder->>Encoder: treat as non-dict payload
        Encoder->>ARTError: create(code = statusCode*100, status = statusCode, message = defaultHTTPMessage)
        Encoder-->>REST: return ARTErrorInfo
    end
    Note over Encoder,REST: statusCode used as primary fallback for missing fields
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review focus:
    • Source/ARTJsonLikeEncoder.m: correctness of type checks (NSDictionary vs others), proper use of statusCode fallbacks and arithmetic (statusCode * 100), memory/error pointer conventions, and comments about non-dictionary payloads.
    • Source/ARTRest.m: ensure every decodeErrorInfo call site now passes response.statusCode and preserves existing error semantics.
    • Test/AblyTests/Tests/UtilitiesTests.swift: remove duplicated tests or confirm intentional duplication; verify assertions match new fallback semantics.
    • Test/AblyTests/Test Utilities/TestUtilities.swift: confirm stubbed response headers and serialized stubData match decoder expectations.

Poem

🐰 I nibbled bytes of JSON, string and map,

Status seeded codes upon my lap.
When errors come odd, be they text or art,
I stitch fallbacks tidy — a rabbit's small part. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: handling HTTP JSON errors that are not dictionaries, which matches the PR's core objective from ECO-5633.
Linked Issues check ✅ Passed The PR successfully implements handling for HTTP JSON error responses where the error field is not a dictionary, supporting both dictionary and string/other payloads with appropriate fallbacks.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of handling non-dictionary error payloads; signature updates, error decoding logic, test utilities, and new tests all support this primary goal.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2135-http-error-response-as-string

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.

@github-actions github-actions bot temporarily deployed to staging/pull/2136/features October 31, 2025 00:25 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/2136/jazzydoc October 31, 2025 00:30 Inactive
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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4e23a51 and 4bd71dc.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (2 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1068-1072)
  • simulateIncomingServerErrorOnNextRequest (1074-1078)
  • data (915-917)
  • execute (832-858)
  • execute (927-938)
  • execute (1016-1066)
Test/AblyTests/Test Utilities/TestUtilities.swift (1)
Test/AblyTests/Test Utilities/JSON.swift (1)
  • jsonObject (79-89)
🪛 SwiftLint (0.57.0)
Test/AblyTests/Tests/UtilitiesTests.swift

[Warning] 255-255: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 288-288: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

⏰ 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). (6)
  • GitHub Check: check
  • GitHub Check: check (tvOS, test_tvOS18_4)
  • GitHub Check: check (macOS, test_macOS)
  • GitHub Check: check (iOS, test_iOS18_4)
  • GitHub Check: build
  • GitHub Check: check

@maratal maratal marked this pull request as draft October 31, 2025 12:31
@maratal maratal force-pushed the 2135-http-error-response-as-string branch from 4bd71dc to e3d37c9 Compare November 1, 2025 03:01
@github-actions github-actions bot temporarily deployed to staging/pull/2136/features November 1, 2025 03:01 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/2136/jazzydoc November 1, 2025 03:04 Inactive
@maratal maratal marked this pull request as ready for review November 1, 2025 13:50
@maratal maratal force-pushed the 2135-http-error-response-as-string branch from e3d37c9 to 76fd593 Compare November 1, 2025 13:52
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

♻️ Duplicate comments (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (1)

899-917: Critical: Fix statusCode calculation in stub JSON.

The calculation on line 909 uses modf(Float(self.value)/100).0, which returns the fractional component, not the whole number part. For error codes like 40400:

  • 40400 / 100 = 404.0
  • modf(404.0) returns (fractionalPart: 0.0, integerPart: 404.0)
  • Accessing .0 yields 0.0 (the fractional part)

This causes all simulated errors to have statusCode: 0 in the JSON payload, undermining the test coverage.

Apply this fix to use integer division:

             let jsonObject: [String: Any] = [
                 "error": [
-                    "statusCode": modf(Float(self.value)/100).0, //whole number part
+                    "statusCode": self.statusCode,
                     "code": self.value,
                     "message": self.description,
                     "serverId": self.serverId,

This uses the already-correct statusCode parameter passed to the initializer.

🧹 Nitpick comments (1)
Source/ARTJsonLikeEncoder.m (1)

1119-1136: Implementation correctly handles both error payload formats.

The decoder now supports:

  • String error: {"error": "message"} → constructs ARTErrorInfo with statusCode * 100 as code
  • Dictionary error: {"error": {"code": 40400, "message": "..."}} → extracts fields with fallback to statusCode-based values

Consider using an empty string @"" or nil instead of @"<Error message was not provided>" on line 1130 to match the behavior when the error field itself is a string (which uses the string value directly). This would provide more consistent behavior across both cases:

-                                    message:decodedError[@"message"] ?: @"<Error message was not provided>"];
+                                    message:decodedError[@"message"] ?: @""];
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd71dc and e3d37c9.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (4 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
Test/AblyTests/Test Utilities/TestUtilities.swift (1)
Test/AblyTests/Test Utilities/JSON.swift (1)
  • jsonObject (79-89)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1085-1089)
  • simulateIncomingServerErrorOnNextRequest (1091-1095)
  • data (932-934)
  • execute (832-858)
  • execute (944-955)
  • execute (1033-1083)
🪛 SwiftLint (0.57.0)
Test/AblyTests/Tests/UtilitiesTests.swift

[Warning] 262-262: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 297-297: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

🔇 Additional comments (6)
Source/PrivateHeaders/Ably/ARTEncoder.h (1)

100-100: LGTM! Protocol signature correctly updated.

The addition of the statusCode parameter enables the decoder to construct proper error information when the error payload lacks explicit status codes.

Test/AblyTests/Tests/UtilitiesTests.swift (2)

242-272: Test correctly validates string error handling.

This test verifies that when the server returns {"error": "Object not found"}, the decoder constructs an ARTErrorInfo with the appropriate code, statusCode, and message.

Note: SwiftLint flags the unused response parameter on line 262. This is acceptable since the test only validates the error, but you can suppress the warning by replacing response with _ if preferred:

-rest.internal.execute(request, wrapperSDKAgents:nil, completion: { response, _, error in
+rest.internal.execute(request, wrapperSDKAgents:nil, completion: { _, _, error in

274-307: Test correctly validates dictionary error handling.

This test verifies that when the server returns a nested error object {"error": {"code": 40400, "message": "Object not found"}}, the decoder extracts the fields properly.

Same SwiftLint note as the previous test—replace response with _ on line 297 if you want to suppress the warning:

-rest.internal.execute(request, wrapperSDKAgents:nil, completion: { response, _, error in
+rest.internal.execute(request, wrapperSDKAgents:nil, completion: { _, _, error in
Source/ARTRest.m (1)

405-407: LGTM! All call sites correctly updated.

All invocations of decodeErrorInfo now pass response.statusCode, enabling the encoder to use it as a fallback when constructing error information. The changes are consistent and correct.

Also applies to: 416-418, 436-439, 567-569

Test/AblyTests/Test Utilities/TestUtilities.swift (2)

931-935: LGTM! Helper extension for JSON serialization.

This extension provides a convenient way to convert dictionary payloads to Data for the error simulator.


1042-1055: LGTM! Improved error simulation API.

The changes enhance TestProxyHTTPExecutor:

  1. Line 1042: Uses let requestURL instead of var _ for better clarity
  2. Line 1085: Adds statusCode and data parameters with sensible defaults, making error simulation more flexible

Also applies to: 1085-1089

@github-actions github-actions bot temporarily deployed to staging/pull/2136/features November 1, 2025 13:53 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/2136/jazzydoc November 1, 2025 13:55 Inactive
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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e3d37c9 and 76fd593.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (4 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1085-1089)
  • simulateIncomingServerErrorOnNextRequest (1091-1095)
  • data (932-934)
  • execute (832-858)
  • execute (944-955)
  • execute (1033-1083)
🪛 SwiftLint (0.57.0)
Test/AblyTests/Tests/UtilitiesTests.swift

[Warning] 262-262: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 297-297: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

⏰ 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). (6)
  • GitHub Check: check (macOS, test_macOS)
  • GitHub Check: check
  • GitHub Check: build
  • GitHub Check: check (tvOS, test_tvOS18_4)
  • GitHub Check: check (iOS, test_iOS18_4)
  • GitHub Check: check

@maratal maratal force-pushed the 2135-http-error-response-as-string branch from 76fd593 to 32cbaf9 Compare November 1, 2025 14:23
@github-actions github-actions bot temporarily deployed to staging/pull/2136/features November 1, 2025 14:24 Inactive
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 (2)
Test/AblyTests/Tests/UtilitiesTests.swift (2)

242-272: Address SwiftLint warning: replace unused closure parameter with underscore.

The response parameter in the completion closure is not used and should be replaced with _ to address the SwiftLint warning.

Apply this diff:

-        rest.internal.execute(request, wrapperSDKAgents:nil, completion: { response, _, error in
+        rest.internal.execute(request, wrapperSDKAgents:nil, completion: { _, _, error in
             guard let error = error as? ARTErrorInfo else {

274-307: Address SwiftLint warning: replace unused closure parameter with underscore.

The response parameter in the completion closure is not used and should be replaced with _ to address the SwiftLint warning.

Apply this diff:

-        rest.internal.execute(request, wrapperSDKAgents:nil, completion: { response, _, error in
+        rest.internal.execute(request, wrapperSDKAgents:nil, completion: { _, _, error in
             guard let error = error as? ARTErrorInfo else {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 76fd593 and 32cbaf9.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (4 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Source/PrivateHeaders/Ably/ARTEncoder.h
🧰 Additional context used
🧬 Code graph analysis (2)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1085-1089)
  • simulateIncomingServerErrorOnNextRequest (1091-1095)
  • data (932-934)
  • execute (832-858)
  • execute (944-955)
  • execute (1033-1083)
Test/AblyTests/Test Utilities/TestUtilities.swift (1)
Test/AblyTests/Test Utilities/JSON.swift (1)
  • jsonObject (79-89)
🪛 SwiftLint (0.57.0)
Test/AblyTests/Tests/UtilitiesTests.swift

[Warning] 262-262: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 297-297: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

⏰ 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). (6)
  • GitHub Check: check
  • GitHub Check: check (tvOS, test_tvOS18_4)
  • GitHub Check: check (macOS, test_macOS)
  • GitHub Check: build
  • GitHub Check: check (iOS, test_iOS18_4)
  • GitHub Check: check
🔇 Additional comments (6)
Source/ARTRest.m (2)

405-418: LGTM! StatusCode propagation is correct.

The changes correctly propagate response.statusCode to the encoder's decodeErrorInfo method and construct artificial errors with appropriate status codes when content type is invalid.


436-439: LGTM! Consistent statusCode handling throughout.

The statusCode parameter is consistently passed to decodeErrorInfo across all error decoding paths, ensuring proper error information construction.

Also applies to: 567-569

Source/ARTJsonLikeEncoder.m (1)

1119-1140: LGTM! Multi-branch error decoding correctly handles both formats.

The implementation properly handles:

  • String error payloads (lines 1121-1126) using statusCode-based defaults
  • Dictionary error payloads (lines 1127-1135) with safe extraction via artNumber/artString helpers
  • Invalid formats (lines 1136-1139) with debug logging

The use of artNumber and artString helpers correctly handles NSNull values by returning nil, which then triggers the nil-coalescing operators to use appropriate defaults. This addresses the concern from the previous review.

Test/AblyTests/Test Utilities/TestUtilities.swift (3)

883-929: LGTM! Enhanced ErrorSimulator with flexible payload support.

The new initializers provide flexibility:

  1. Explicit stubData initializer (lines 891-897) for pre-serialized payloads
  2. stubDataDict initializer (lines 899-917) that builds default error JSON or accepts custom dictionaries

The stubResponse method (lines 919-928) correctly builds HTTP responses with Ably-specific headers derived from error fields.


931-935: LGTM! Concise dictionary-to-Data extension.

The extension provides a convenient way to serialize dictionaries for test payloads, with appropriate error handling via optional return type.


1042-1055: LGTM! Improved error simulation API.

The updates provide:

  • Optional statusCode and data parameters for flexible error simulation (line 1085)
  • Overload accepting pre-built ErrorSimulator instances (lines 1091-1095)
  • Cleaner if let unwrapping pattern (line 1042) instead of if var

These changes enable the new test scenarios for error decoding with both string and dictionary payloads.

Also applies to: 1085-1095

Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian left a comment

Choose a reason for hiding this comment

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

If you believe that this fixes the customer's crash (which it sounds like is urgent for them), then we can merge it and do a release. But I believe that we're just covering up a broader issue — see #2135. If we do merge this, we should revert it soon and do a proper fix. What do you think?

@maratal
Copy link
Collaborator Author

maratal commented Nov 6, 2025

If you believe that this fixes the customer's crash (which it sounds like is urgent for them), then we can merge it and do a release. But I believe that we're just covering up a broader issue — see #2135. If we do merge this, we should revert it soon and do a proper fix. What do you think?

I think that the exact behavior should be formalized in the specs and until then we can release this fix. I don't think it should be reverted though, but rather be applied on top because error parser method will be unchanged or even extended and the http callback rewritten significantly.

@lawrence-forooghian
Copy link
Collaborator

I don't think it should be reverted though, but rather be applied on top because error parser method will be unchanged or even extended

Why would we need to handle an error being an NSString? In fact, now that I look at it, why do we even want such a handling now? There's no reason to expect a string-valued error in the response body. We should just make sure that we do something sensible in the case where the error is missing or not a dictionary, no?

@maratal
Copy link
Collaborator Author

maratal commented Nov 6, 2025

I don't think it should be reverted though, but rather be applied on top because error parser method will be unchanged or even extended

Why would we need to handle an error being an NSString? In fact, now that I look at it, why do we even want such a handling now? There's no reason to expect a string-valued error in the response body. We should just make sure that we do something sensible in the case where the error is missing or not a dictionary, no?

Well, technically you are right, and I could just do this:

        return [ARTErrorInfo createWithCode:statusCode * 100
                                     status:statusCode
                                    message:@"<empty message>"];

But since we've already have decodedError as string error message, why not just put it there instead?

@lawrence-forooghian
Copy link
Collaborator

lawrence-forooghian commented Nov 6, 2025

I'm confused; why would we try and pick values out of any random API response that somebody might throw at us? It seems to me that trying to handle error: String in the response is no different to trying to handle any other arbitrary key-value pair in the response (e.g. errorCode: Int or fooCorpCustomErrorDescription: String).

@maratal
Copy link
Collaborator Author

maratal commented Nov 6, 2025

I'm confused; why would we try and pick values out of any random API response that somebody might throw at us? It seems to me that trying to handle error: String in the response is no different to trying to handle any other arbitrary key-value pair in the response (e.g. errorCode: Int or fooCorpCustomErrorDescription: String).

Ok, will remove. Should it be an empty string then in [ARTErrorInfo createWithCode:status:message:]?

@lawrence-forooghian
Copy link
Collaborator

Should it be an empty string then in [ARTErrorInfo createWithCode:status:message:]?

I would suggest just having a fallback error message something like "HTTP request failed with status code \(statusCode)". And I'd add a comment explaining why we have this handling (i.e. we are currently mistakenly trying to handle authURL responses as if they were from the Ably REST API, so we need to not blow up if there isn't an Ably-formatted error, but that we'll fix this properly soon, with a link to a GitHub issue).

@lawrence-forooghian
Copy link
Collaborator

with a link to a GitHub issue

actually it can be #2135; let's just not mark that as closed in this PR

@maratal maratal force-pushed the 2135-http-error-response-as-string branch from 32cbaf9 to cd70fb1 Compare November 7, 2025 15:19
@maratal maratal changed the title [ECO-5633] Add handling http JSON error field as string. [ECO-5633] Add handling http JSON error which is not dictionary. Nov 7, 2025
@github-actions github-actions bot temporarily deployed to staging/pull/2136/features November 7, 2025 15:19 Inactive
@maratal
Copy link
Collaborator Author

maratal commented Nov 7, 2025

@lawrence-forooghian fixed

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 32cbaf9 and cd70fb1.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (4 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Source/PrivateHeaders/Ably/ARTEncoder.h
  • Test/AblyTests/Test Utilities/TestUtilities.swift
🧰 Additional context used
🧬 Code graph analysis (1)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1085-1089)
  • simulateIncomingServerErrorOnNextRequest (1091-1095)
  • data (932-934)
  • execute (832-858)
  • execute (944-955)
  • execute (1033-1083)
⏰ 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). (6)
  • GitHub Check: check
  • GitHub Check: check
  • GitHub Check: build
  • GitHub Check: check (macOS, test_macOS)
  • GitHub Check: check (iOS, test_iOS18_4)
  • GitHub Check: check (tvOS, test_tvOS18_4)
🔇 Additional comments (4)
Source/ARTRest.m (2)

405-440: LGTM! Error handling correctly updated.

The changes properly propagate statusCode through the error decoding flow, aligning with the updated ARTEncoder protocol signature. The multi-line formatting improves readability without changing semantics.


567-569: LGTM! Consistent error handling update.

The statusCode parameter is correctly passed to decodeErrorInfo in the time method, maintaining consistency with other call sites.

Test/AblyTests/Tests/UtilitiesTests.swift (2)

274-307: Test logic is correct.

The test properly verifies error extraction when the response contains a complete error info dictionary with code and message fields.


242-272: Test logic is correct; no duplication detected.

The test properly verifies the fallback behavior when the error response doesn't contain a dictionary error field, returning a generic HTTP status code message. Verification of the file shows these are two distinct test methods (with_only_error_field at line 242 and with_complete_error_info at line 274), each testing different scenarios—no duplication exists.

@github-actions github-actions bot temporarily deployed to staging/pull/2136/jazzydoc November 7, 2025 15:23 Inactive
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)
Test/AblyTests/Tests/UtilitiesTests.swift (1)

242-307: Cover the string-valued error field explicitly

Could we tweak one of these stubs so the payload includes "error": "Object not found"? That would exercise the exact shape that triggered ECO-5633 and guarantee this guard keeps working.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cd70fb1 and 78b61c1.

📒 Files selected for processing (5)
  • Source/ARTJsonLikeEncoder.m (1 hunks)
  • Source/ARTRest.m (4 hunks)
  • Source/PrivateHeaders/Ably/ARTEncoder.h (1 hunks)
  • Test/AblyTests/Test Utilities/TestUtilities.swift (4 hunks)
  • Test/AblyTests/Tests/UtilitiesTests.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Source/ARTRest.m
🧰 Additional context used
🧬 Code graph analysis (2)
Test/AblyTests/Tests/UtilitiesTests.swift (1)
Test/AblyTests/Test Utilities/TestUtilities.swift (8)
  • commonAppSetup (107-142)
  • clientOptions (144-159)
  • simulateIncomingServerErrorOnNextRequest (1085-1089)
  • simulateIncomingServerErrorOnNextRequest (1091-1095)
  • data (932-934)
  • execute (832-858)
  • execute (944-955)
  • execute (1033-1083)
Test/AblyTests/Test Utilities/TestUtilities.swift (1)
Test/AblyTests/Test Utilities/JSON.swift (1)
  • jsonObject (79-89)
🪛 SwiftLint (0.57.0)
Test/AblyTests/Tests/UtilitiesTests.swift

[Warning] 262-262: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 297-297: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

⏰ 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). (6)
  • GitHub Check: check
  • GitHub Check: build
  • GitHub Check: check (iOS, test_iOS18_4)
  • GitHub Check: check (macOS, test_macOS)
  • GitHub Check: check (tvOS, test_tvOS18_4)
  • GitHub Check: check
🔇 Additional comments (4)
Source/PrivateHeaders/Ably/ARTEncoder.h (1)

100-101: Carry status codes through the decode contract

Great to see the status code flowing through the encoder API; that'll keep downstream contexts aligned with the HTTP layer.

Source/ARTJsonLikeEncoder.m (1)

1119-1136: Robust fallback for non-dictionary error payloads

Appreciate the type guard plus fallback message—this removes the crash we saw with string payloads while still surfacing a sensible ARTErrorInfo.

Test/AblyTests/Test Utilities/TestUtilities.swift (2)

883-918: Nice helper for pre-serialized stub payloads

The tailored initializers plus the [String: Any].data() helper make it far simpler to craft realistic server responses in tests while keeping the Ably headers intact.


1042-1053: Stub responses now surface deterministic bodies

Reusing the stored stubData whether or not the underlying request runs keeps the executor’s behaviour predictable for callers—thanks for tightening that up.

@maratal maratal merged commit 397722d into main Nov 7, 2025
11 of 12 checks passed
@maratal maratal deleted the 2135-http-error-response-as-string branch November 7, 2025 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants