Skip to content

Harmonise ReadBlob: rename Source→Input, add error handling (v3.0.0)#118

Open
jefim wants to merge 3 commits intomainfrom
harmonize-readblob
Open

Harmonise ReadBlob: rename Source→Input, add error handling (v3.0.0)#118
jefim wants to merge 3 commits intomainfrom
harmonize-readblob

Conversation

@jefim
Copy link
Copy Markdown
Contributor

@jefim jefim commented Apr 17, 2026

Summary

  • [Breaking] Renamed Source tab to Input — update task parameter references from Source to Input when upgrading; ContainerName and BlobName properties are unchanged.
  • Added Options.ThrowErrorOnFailure (default: true) and Options.ErrorMessageOnFailure to control error behaviour.
  • Added Result.Success (bool) and Result.Error { Message, AdditionalInfo } to the result object.
  • Created Helpers/ErrorHandler.cs and Definitions/Error.cs following the standard Frends error handling pattern.
  • Bumped version to 3.0.0.

Resolves FSPW-397.

Test plan

  • Existing integration tests (SAS, ConnectionString, OAuth2) updated to use Input and assert Success = true
  • New unit tests for ThrowErrorOnFailure = false returning error in result
  • New unit tests for ThrowErrorOnFailure = true with custom message throwing correct exception
  • Build passes with 0 warnings and 0 errors (dotnet build)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Breaking Changes

    • Parameter renamed: Source tab is now Input. Update existing task configurations accordingly.
    • Package version bumped to 3.0.0.
  • New Features

    • Added ThrowErrorOnFailure option (default: true) to control whether errors are thrown or returned in results.
    • Added ErrorMessageOnFailure option to customize error message prefixes.
    • Error responses now include Success status and structured error details when exceptions are not thrown.

…uccess/Error result

- Renamed Source class/tab to Input (breaking: update task parameter references)
- Added Options.ThrowErrorOnFailure (default true) and Options.ErrorMessageOnFailure
- Added Result.Success (bool) and Result.Error { Message, AdditionalInfo }
- Created Helpers/ErrorHandler.cs following standard Frends error handling pattern
- Created Definitions/Error.cs for structured error details
- Bumped version to 3.0.0 (breaking changes)
- Updated tests: renamed Source→Input, added error handling test cases
- Updated CHANGELOG.md with upgrade instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 17, 2026

Warning

Rate limit exceeded

@MichalFrends1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 1 second before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2bcc369-f065-4273-bd3b-16ff652255d4

📥 Commits

Reviewing files that changed from the base of the PR and between d5d22cb and 7d76f0d.

📒 Files selected for processing (4)
  • Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob.Tests/ErrorHandlerTest.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob.Tests/UnitTests.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/migration.json

Walkthrough

The PR introduces breaking changes to the ReadBlob task: renames the Source parameter class to Input, adds configuration options for error handling behavior via ThrowErrorOnFailure and ErrorMessageOnFailure, creates an Error class to represent error details, and extends Result with Success and Error properties. Version bumped to 3.0.0.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Documents version 3.0.0 breaking changes: Source renamed to Input, new error handling options, and updated Result structure with Success and Error fields.
Definition Classes
Definitions/Input.cs, Definitions/Options.cs, Definitions/Result.cs, Definitions/Error.cs
Source class renamed to Input; Options extended with ThrowErrorOnFailure (default true) and ErrorMessageOnFailure (default empty); Result properties changed to publicly settable with new Success boolean and Error object fields; new Error class added to encapsulate error messages and additional info.
Implementation
ReadBlob.cs, Helpers/ErrorHandler.cs
ReadBlob method signature updated to accept Input instead of Source; exception handling wrapped around blob operations; delegates error handling to new ErrorHandler.Handle() which conditionally throws or returns errors in Result based on ThrowErrorOnFailure option, with support for custom error message prefixes.
Project & Tests
Frends.AzureBlobStorage.ReadBlob.csproj, UnitTests.cs
Package version incremented from 2.0.0 to 3.0.0; test suite refactored to use Input instead of Source; success assertions updated to check result.Result.Success; validation tests modified to expect generic Exception rather than ValidationException; new test cases added for ThrowErrorOnFailure = false scenarios and custom error message behavior.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant ReadBlob as ReadBlob.cs
    participant ErrorHandler as ErrorHandler
    participant Result as Result

    Caller->>ReadBlob: Call ReadBlob(input, connection, options)
    activate ReadBlob
    
    alt Success Path
        ReadBlob->>ReadBlob: Validate & download blob
        ReadBlob->>Result: Create Result with Success=true, Content, Error=null
        Result-->>ReadBlob: Result object
        ReadBlob-->>Caller: Return Result
    else Exception Path
        ReadBlob->>ReadBlob: Exception caught
        ReadBlob->>ErrorHandler: Handle(exception, ThrowErrorOnFailure, ErrorMessageOnFailure)
        activate ErrorHandler
        
        alt ThrowErrorOnFailure = true
            ErrorHandler->>ErrorHandler: Create Exception with custom message
            ErrorHandler-->>ReadBlob: Throw Exception
            ReadBlob-->>Caller: Exception propagates
        else ThrowErrorOnFailure = false
            ErrorHandler->>Result: Create Result with Success=false, Error populated
            ErrorHandler-->>ReadBlob: Return Result
            ReadBlob-->>Caller: Return Result with Error details
        end
        deactivate ErrorHandler
    end
    
    deactivate ReadBlob
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • MichalFrends1
  • MatteoDelOmbra
  • ttossavainen

Poem

🐰 Hop along with breaking change so grand,
Input hops in where Source once did stand,
Errors now caught with options so fine,
Success and failures both align,
Version three hops into the light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately summarizes the main breaking changes: renaming Source to Input and adding error handling, with version bump to 3.0.0.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch harmonize-readblob

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
Copy Markdown

@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: 3

🧹 Nitpick comments (2)
Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md (1)

5-11: Categorize new items under Added rather than Changed.

Per Keep a Changelog, new features/options (Options.ThrowErrorOnFailure, Options.ErrorMessageOnFailure, Result.Success, Result.Error) belong under ### Added, while the SourceInput rename stays under ### Changed. Current structure lumps everything under Changed.

📝 Proposed structure
 ### Changed

 - [Breaking] Renamed `Source` tab to `Input` tab; move task parameter references from `Source` to `Input` when upgrading.
+
+### Added
+
 - Added `Options.ThrowErrorOnFailure` (default: `true`) — when `false`, errors are returned in the result instead of thrown.
 - Added `Options.ErrorMessageOnFailure` — custom error message prefix for thrown exceptions or returned errors.
 - Added `Result.Success` (bool) — `true` on success, `false` on failure.
 - Added `Result.Error` (object `{ string Message, object AdditionalInfo }`) — populated on failure when `ThrowErrorOnFailure` is `false`.

As per coding guidelines, "Validate format against Keep a Changelog".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md` around lines 5 - 11, Split the
changelog entries so that the rename of `Source` → `Input` remains under the
"### Changed" section, and move the new API/features
(`Options.ThrowErrorOnFailure`, `Options.ErrorMessageOnFailure`,
`Result.Success`, `Result.Error`) into a new "### Added" section; update the
headings and ordering in CHANGELOG.md to follow Keep a Changelog format so
additions are under "Added" and only breaking/rename items remain under
"Changed".
Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Helpers/ErrorHandler.cs (1)

10-16: Avoid throwing the base System.Exception type.

Throwing new Exception(...) is discouraged (analyzer CA2201) because callers cannot catch it selectively without also catching every other failure. Consider InvalidOperationException (or a task-specific exception) and preserve the original as InnerException — which you already do.

♻️ Suggested change
-        if (throwOnFailure)
-        {
-            if (string.IsNullOrEmpty(errorMessageOnFailure))
-                throw new Exception(exception.Message, exception);
-
-            throw new Exception(errorMessageOnFailure, exception);
-        }
+        if (throwOnFailure)
+        {
+            var message = string.IsNullOrEmpty(errorMessageOnFailure)
+                ? exception.Message
+                : errorMessageOnFailure;
+            throw new InvalidOperationException(message, exception);
+        }

Note: this changes the thrown exception type, so any tests asserting on Exception specifically should be reviewed accordingly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Helpers/ErrorHandler.cs`
around lines 10 - 16, The code currently throws System.Exception in the error
handling branch (the throw new Exception(...) lines in ErrorHandler.cs); replace
those with a more specific exception type such as InvalidOperationException (or
a task-specific custom exception) and preserve the original exception as the
InnerException (i.e., throw new InvalidOperationException(errorMessageOnFailure
?? exception.Message, exception)); update any tests that assert on Exception to
expect the new exception type if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md`:
- Around line 3-17: The CHANGELOG has a date mismatch: the 3.0.0 heading shows
2026-04-17 which is earlier than the 2.0.0 entry dated 2026-04-26; update the
3.0.0 release date (the heading "## [3.0.0] - 2026-04-17") to the correct
chronological date (or correct 2.0.0 if that one was wrong) so release order is
chronological, preserving the 3.0.0 changelist text and the 2.0.0 header.

In
`@Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob.Tests/UnitTests.cs`:
- Around line 157-160: Change the test to assert the specific
ValidationException and use the constraint form for message checking: replace
Assert.ThrowsAsync<Exception>(() => AzureBlobStorage.ReadBlob(...)) with
Assert.ThrowsAsync<ValidationException>(() => AzureBlobStorage.ReadBlob(...))
and replace the boolean message assertion
Assert.That(ex.Message.Contains("SasToken is required."), ex.Message) with
Assert.That(ex.Message, Does.Contain("SasToken is required.")); apply the same
two changes for the other failing test that checks "ConnectionString is
required." so both tests use ValidationException and Does.Contain for message
assertions.

In
`@Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Helpers/ErrorHandler.cs`:
- Around line 8-28: The ErrorHandler.Handle method currently converts
OperationCanceledException/TaskCanceledException into generic failures; update
Handle (or the caller in ReadBlob) to let cancellation propagate: check for
exception is OperationCanceledException or TaskCanceledException at the start of
ErrorHandler.Handle and rethrow it immediately (regardless of throwOnFailure),
or alternatively add an exception filter in ReadBlob's catch to rethrow when ex
is a cancellation exception before calling ErrorHandler.Handle; reference
ErrorHandler.Handle and ReadBlob's catch/throwOnFailure so the change is applied
to the correct locations.

---

Nitpick comments:
In `@Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md`:
- Around line 5-11: Split the changelog entries so that the rename of `Source` →
`Input` remains under the "### Changed" section, and move the new API/features
(`Options.ThrowErrorOnFailure`, `Options.ErrorMessageOnFailure`,
`Result.Success`, `Result.Error`) into a new "### Added" section; update the
headings and ordering in CHANGELOG.md to follow Keep a Changelog format so
additions are under "Added" and only breaking/rename items remain under
"Changed".

In
`@Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Helpers/ErrorHandler.cs`:
- Around line 10-16: The code currently throws System.Exception in the error
handling branch (the throw new Exception(...) lines in ErrorHandler.cs); replace
those with a more specific exception type such as InvalidOperationException (or
a task-specific custom exception) and preserve the original exception as the
InnerException (i.e., throw new InvalidOperationException(errorMessageOnFailure
?? exception.Message, exception)); update any tests that assert on Exception to
expect the new exception type if needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3561b607-508f-4f5d-8034-d3cd4312f48d

📥 Commits

Reviewing files that changed from the base of the PR and between 1eca46d and d5d22cb.

📒 Files selected for processing (9)
  • Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob.Tests/UnitTests.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Definitions/Error.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Definitions/Input.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Definitions/Options.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Definitions/Result.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob.csproj
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/Helpers/ErrorHandler.cs
  • Frends.AzureBlobStorage.ReadBlob/Frends.AzureBlobStorage.ReadBlob/ReadBlob.cs

Comment thread Frends.AzureBlobStorage.ReadBlob/CHANGELOG.md Outdated
- Added `Result.Success` (bool) — `true` on success, `false` on failure.
- Added `Result.Error` (object `{ string Message, object AdditionalInfo }`) — populated on failure when `ThrowErrorOnFailure` is `false`.

#### Upgrade instructions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove update notes from changelog

### Changed

- [Breaking] Renamed `Source` tab to `Input` tab; move task parameter references from `Source` to `Input` when upgrading.
- Added `Options.ThrowErrorOnFailure` (default: `true`) — when `false`, errors are returned in the result instead of thrown.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

move added to added header

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.

3 participants