Skip to content

Handle nullable in RestClientException#134

Merged
twogood merged 4 commits intomainfrom
nullable-RestClientException
Oct 28, 2025
Merged

Handle nullable in RestClientException#134
twogood merged 4 commits intomainfrom
nullable-RestClientException

Conversation

@twogood
Copy link
Owner

@twogood twogood commented Oct 28, 2025

Summary by CodeRabbit

Release Notes

  • Tests

    • Enhanced error response validation with null-safety checks in async/sync and XML test scenarios.
  • Refactor

    • Simplified Part API now uses an immutable record structure with optional properties.
    • RestClientException properties and parameters updated to support nullable request URIs and error responses for improved null safety.

@coderabbitai
Copy link

coderabbitai bot commented Oct 28, 2025

Walkthrough

The pull request introduces nullability throughout the error-handling and multi-part request APIs. Test files add runtime null checks for deserialized error responses. Part.cs is refactored from a mutable class hierarchy to an immutable record with positional parameters. RestClientException members are made nullable with adjusted constructor signatures. File-scoped namespaces replace explicit namespace declarations.

Changes

Cohort / File(s) Summary
Test null-check assertions
Activout.RestClient.Test.Json/RestClientTests.cs, Activout.RestClient.Xml.Test/ErrorResponseXmlTest.cs
Added runtime assertions verifying that error objects deserialized from GetErrorResponse<T>() are not null in async and sync test paths.
Part type refactoring
Activout.RestClient/Part.cs
Replaces mutable Part class and Part<T> generic wrapper with immutable record Part(object Content, string? Name, string? FileName = null). Removes InternalContent and generic inheritance pattern. Adopts file-scoped namespace.
RestClientException nullability
Activout.RestClient/RestClientException.cs
Makes RequestUri, ErrorResponse, and GetErrorResponse<T>() return type nullable. Updates constructor signatures to accept nullable requestUri, errorResponse, and innerException parameters. Adopts file-scoped namespace.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Part.cs requires careful review of the record conversion and breaking API changes; verify all call sites adapt to the new immutable structure and positional parameter semantics.
  • RestClientException.cs nullability changes should be traced through dependent code to ensure callers handle nullable properties correctly.
  • Test changes are straightforward assertions but confirm they align with the exception handling expectations.

Possibly related PRs

Poem

🐰 From classes mutable, now records immune,
Our errors now nullable—no more presume!
File-scoped namespaces tidy the way,
Tests catch the nulls—hooray, hooray!
Immutability reigns from this day. 🎉

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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Handle nullable in RestClientException" directly refers to one of the significant changes in the changeset: the RestClientException.cs modifications that introduce nullable handling across constructors, properties, and the GetErrorResponse method. The title is clear, specific, and accurately describes the work done on that component. However, the changeset also includes substantial changes to Part.cs (marked as high code review effort) that refactors the class structure from a mutable hierarchy to an immutable record with file-scoped namespaces, along with test file updates. The title captures one important aspect of the pull request but does not encompass the full scope of the changes.
✨ 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 nullable-RestClientException

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.

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

🧹 Nitpick comments (4)
Activout.RestClient/RestClientException.cs (3)

8-23: Consolidate the two ctors via a primary constructor to remove duplication

You can express this exception with one primary constructor that also passes message/innerException to the base. Clearer, less code, same behavior.

Apply:

- public class RestClientException : Exception
- {
-     public RestClientException(Uri? requestUri, HttpStatusCode statusCode, object? errorResponse)
-         : base(errorResponse?.ToString())
-     {
-         RequestUri = requestUri;
-         StatusCode = statusCode;
-         ErrorResponse = errorResponse;
-     }
-
-     public RestClientException(Uri? requestUri, HttpStatusCode statusCode, string? errorResponse,
-         Exception? innerException)
-         : base(errorResponse, innerException)
-     {
-         RequestUri = requestUri;
-         StatusCode = statusCode;
-         ErrorResponse = errorResponse;
-     }
- 
-     public Uri? RequestUri { get; }
-     public HttpStatusCode StatusCode { get; }
-     public object? ErrorResponse { get; }
-     ...
- }
+ public class RestClientException(Uri? requestUri, HttpStatusCode statusCode, object? errorResponse, Exception? innerException = null)
+     : Exception(errorResponse?.ToString(), innerException)
+ {
+     public Uri? RequestUri { get; } = requestUri;
+     public HttpStatusCode StatusCode { get; } = statusCode;
+     public object? ErrorResponse { get; } = errorResponse;
+     // remaining members unchanged (see below for expression-bodied tweaks)
+ }

As per coding guidelines.


30-33: Consider expression-bodied + a safe Try-get helper

  • Minimal tweak (no behavior change): make this expression-bodied.
  • Optional: add TryGetErrorResponse(out T?) that uses pattern matching to avoid InvalidCastException on mismatched T.

Apply minimal tweak:

-    public T? GetErrorResponse<T>()
-    {
-        return (T?)ErrorResponse;
-    }
+    public T? GetErrorResponse<T>() => (T?)ErrorResponse;

Optionally add:

public bool TryGetErrorResponse<T>(out T? result)
{
    if (ErrorResponse is T t) { result = t; return true; }
    result = default;
    return false;
}

As per coding guidelines.


35-39: Prefer expression-bodied ToString for brevity

Same output, cleaner form.

-    public override string ToString()
-    {
-        return
-            $"{base.ToString()}, {nameof(RequestUri)}: {RequestUri}, {nameof(StatusCode)}: {StatusCode}, {nameof(ErrorResponse)}: {ErrorResponse}";
-    }
+    public override string ToString() =>
+        $"{base.ToString()}, {nameof(RequestUri)}: {RequestUri}, {nameof(StatusCode)}: {StatusCode}, {nameof(ErrorResponse)}: {ErrorResponse}";

As per coding guidelines.

Activout.RestClient.Xml.Test/ErrorResponseXmlTest.cs (1)

54-56: Added NotNull guard: good

Keeps nullability honest after GetErrorResponse<T?> change. LGTM.

Optionally, use pattern matching to both assert and capture:

if (exception.GetErrorResponse<XmlErrorResponse>() is { } errorResponse)
{
    Assert.Equal(400, errorResponse.Code);
    Assert.Equal("Invalid request parameter", errorResponse.Message);
}
else
{
    Assert.Fail("Expected XmlErrorResponse.");
}

[Based on coding guidelines]

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8654030 and 8b8356b.

📒 Files selected for processing (4)
  • Activout.RestClient.Test.Json/RestClientTests.cs (2 hunks)
  • Activout.RestClient.Xml.Test/ErrorResponseXmlTest.cs (1 hunks)
  • Activout.RestClient/Part.cs (1 hunks)
  • Activout.RestClient/RestClientException.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.cs: Use [] list syntax for collections
Use file-scoped namespaces
Use primary constructors wherever possible
Use records for data transfer objects (DTOs) and immutable data structures
Use var for local variable declarations when possible
Use expression-bodied members for simple methods and properties
Use pattern matching for type checks and deconstruction
Use using statements for resource management
Use async and await for asynchronous programming
Never include "Async" in method names
Only include comments that explain why something is done, not what is done

Files:

  • Activout.RestClient.Test.Json/RestClientTests.cs
  • Activout.RestClient.Xml.Test/ErrorResponseXmlTest.cs
  • Activout.RestClient/RestClientException.cs
  • Activout.RestClient/Part.cs
🔇 Additional comments (3)
Activout.RestClient/RestClientException.cs (2)

4-4: File-scoped namespace: good move

Matches the guideline and reduces nesting noise. [Based on coding guidelines]


25-29: Property nullability looks correct

Public surface now accurately reflects possible nulls. LGTM.

Activout.RestClient.Test.Json/RestClientTests.cs (1)

115-116: Non-null asserts after GetErrorResponse<T?>: good

Matches new nullable return, prevents accidental null deref in tests. LGTM.

Also applies to: 169-170

@twogood twogood enabled auto-merge (squash) October 28, 2025 09:08
@twogood twogood merged commit 41f85b0 into main Oct 28, 2025
9 checks passed
@twogood twogood deleted the nullable-RestClientException branch October 28, 2025 09:09
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

Comments