Skip to content

Nexus Error Serialization Update#630

Merged
Quinn-With-Two-Ns merged 7 commits into
temporalio:mainfrom
Quinn-With-Two-Ns:nexus-error-seralization
Mar 31, 2026
Merged

Nexus Error Serialization Update#630
Quinn-With-Two-Ns merged 7 commits into
temporalio:mainfrom
Quinn-With-Two-Ns:nexus-error-seralization

Conversation

@Quinn-With-Two-Ns

@Quinn-With-Two-Ns Quinn-With-Two-Ns commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Switch dotnet SDK to the new Nexus failure serialization format we are using in Go, Java, Python and soon TS.

Summary

  • ToException() for NexusHandlerFailureInfo now returns HandlerException (NexusRpc type) instead of NexusHandlerFailureException,
    matching Python's nexusrpc.HandlerError
  • ToFailure() handles HandlerException with NexusHandlerFailureInfo and recursive cause chains
  • OperationException: Failed → ApplicationFailureException("OperationError"), Canceled → CanceledFailureException
  • Removed ExceptionToNexusFailureAsync() and FetchResultAsync/FetchInfoAsync stubs

Breaking Changes

  • Callers now receive HandlerException instead of NexusHandlerFailureException in the Nexus error chain

Note

Medium Risk
Changes Nexus error/Failure serialization and exception types surfaced to callers (HandlerException instead of NexusHandlerFailureException), which can break error-handling code and affects cross-language interoperability and retry semantics.

Overview
Switches Nexus error propagation to the newer cross-SDK format by treating NexusRpc.Handlers.HandlerException as the primary Nexus handler error type and round-tripping it through Temporal Failure protos.

DefaultFailureConverter now (1) serializes fresh HandlerExceptions into NexusHandlerFailureInfo, (2) deserializes NexusHandlerFailureInfo into HandlerException (including retry behavior) while preserving original Temporal failure structure via JSON proto round-tripping, and (3) adds support for non-Temporal Nexus failure payload fallbacks.

NexusWorker now returns Failure directly (removing deprecated Error/OperationError paths) and maps OperationException states to CanceledFailureException or a non-retryable ApplicationFailureException("OperationError"), preserving cause chains; related IOperationHandler FetchInfoAsync/FetchResultAsync stubs are removed across hosting/worker/test helpers. Tests are updated/expanded accordingly, and NexusRpc is bumped to 0.3.0.

Written by Cursor Bugbot for commit 7c4ce26. This will update automatically on new commits. Configure here.

TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Current)).ConfigureAwait(false);

public async Task<OperationInfo> FetchInfoAsync(OperationFetchInfoContext context) =>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This change is just from updating the Nexus RPC library

<PackageReference Include="Google.Protobuf" Version="3.26.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="NexusRpc" Version="0.2.0" />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Need to release the Nexus SDK before merging

@VegetarianOrc VegetarianOrc left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overall looks good to me! There's a bunch of references to the Python implementation that are sprinkled throughout docstrings or comments that I think we should remove. I commented on two but there were more.

A couple other minor suggestions/comments.

Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs Outdated
Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs Outdated
Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs Outdated
Comment on lines +123 to +134
// Simulate a round-trip: an ApplicationFailureInfo that was serialized to
// NexusRpc.Failure and is now being restored
var originalProto = new Failure()
{
Message = "Original error",
StackTrace = "at SomeMethod()",
ApplicationFailureInfo = new()
{
Type = "CustomError",
NonRetryable = true,
},
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm not sure what I think about this test. I feel like what it's testing is a reasonable assertion, but is it realistic that a HandlerError would have an OriginalFailure where the info type isn't NexusHandlerFailureInfo?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated this test let me know what you think

Comment thread tests/Temporalio.Tests/Worker/NexusWorkerTests.cs Outdated
@Quinn-With-Two-Ns Quinn-With-Two-Ns marked this pull request as ready for review March 26, 2026 15:48
@Quinn-With-Two-Ns Quinn-With-Two-Ns requested a review from a team as a code owner March 26, 2026 15:48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18c6aa2e32

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Temporalio/Temporalio.csproj Outdated
Comment thread src/Temporalio/Worker/NexusWorker.cs
Comment thread src/Temporalio/Temporalio.csproj Outdated
Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs Outdated
Comment thread src/Temporalio/Worker/NexusWorker.cs
Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs Outdated
Comment thread src/Temporalio/Worker/NexusWorker.cs
@Quinn-With-Two-Ns Quinn-With-Two-Ns force-pushed the nexus-error-seralization branch from dc140dd to 7c4ce26 Compare March 31, 2026 17:54

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Comment thread src/Temporalio/Converters/DefaultFailureConverter.cs
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