DcsvIo.D2.Result.Grpc 0.1.1

dotnet add package DcsvIo.D2.Result.Grpc --version 0.1.1
                    
NuGet\Install-Package DcsvIo.D2.Result.Grpc -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DcsvIo.D2.Result.Grpc" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DcsvIo.D2.Result.Grpc" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="DcsvIo.D2.Result.Grpc" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DcsvIo.D2.Result.Grpc --version 0.1.1
                    
#r "nuget: DcsvIo.D2.Result.Grpc, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DcsvIo.D2.Result.Grpc@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DcsvIo.D2.Result.Grpc&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=DcsvIo.D2.Result.Grpc&version=0.1.1
                    
Install as a Cake Tool

DcsvIo.D2.Result.Grpc

Faithful in-memory → wire → in-memory D2Result round-trip over a gRPC D2ResultProto response envelope. Every service handler returns a D2Result as-is; the framework wraps it; the consumer re-materializes an equal D2Result on the other side — zero caller try-catch for business failures.

Install

dotnet add package DcsvIo.D2.Result.Grpc

Core API

// Server side: wrap
var response = new FindThingsResponse
{
    Result = result.ToProto(),
};
response.Data.AddRange(things);
return response;

// Consumer side: re-materialize
var res = await client.FindThings(req).HandleAsync(r => r.Result, r => r.Data);
if (res.Category == ErrorCategory.NotFound) { /* typed, no registry lookup */ }
res.StatusCode == HttpStatusCode.Conflict; // exact HTTP status, not a lossy gRPC bucket

Key properties

  • Full fidelity: every field — Success, StatusCode (exact integer), ErrorCode, Category, Messages (key + params), InputErrors, TraceId, Data — round-trips equal.
  • Typed ErrorCategory: populated by factories at generation time. ErrorCategory.NotFound is available directly on the rebuilt result; no runtime registry lookup on the hot path.
  • TKMessageProto: structured message carrier (key + map<string,string> params). Full parameter fidelity — a TKMessage with substitution bindings survives the round-trip unchanged.
  • Transport fault fail-open: RpcExceptionServiceUnavailable; CancelledCanceled; any other ExceptionUnhandledException. User-facing messages stay the factory TK constants — never raw transport strings.
  • PII-safe logging: [LoggerMessage] signatures do NOT accept Exception. Transport detail is logged via SanitizedExceptionRender.TypeName + FirstFrame + StatusCode — never ex.Message (which can embed AMQP URIs, JWT contents, configured secrets).
  • IsTransientGrpcException: classifies DeadlineExceeded, ResourceExhausted, Aborted, Internal, Unavailable as transient for retry callers.

Wire mechanism boundary

Two mechanisms coexist on every gRPC call — each has a distinct role and must not be conflated:

Mechanism What it carries gRPC status on the wire Who reads it
D2ResultProto response envelope (this lib) Business results — both success and failure. A handler returning NotFound() or ValidationFailed() produces a normal gRPC OK response; the failure detail rides inside the D2ResultProto result envelope field. gRPC OK (status 0) + response body HandleAsync / ToD2Result<T> — caller gets a clean D2Result with zero try-catch for business failures
RpcException + D2GrpcTrailers (host-supplied auth/transport binding) Transport/auth rejections — JWT validation failure, JWKS unavailable, scope insufficient. These are genuine transport-layer faults, not handler outcomes. Non-OK gRPC status (Unauthenticated (16) or Unavailable (14)) + trailers (d2_error_code / d2_messages / traceId) Auth middleware on the server side; retry/circuit-breaker on the client side

Boundary rule: a 401 from the JWT interceptor is RpcException(Unauthenticated) — never a D2ResultProto{ success=false, status_code=401 }. A 404 from a handler is D2ResultProto{ success=false, status_code=404 } — never an RpcException. The two paths are structurally separate and must stay that way.

Proto contract

The shared d2_result.proto contract is the single source of truth. Generated D2ResultProto / TKMessageProto / InputErrorProto types live in namespace D2.Services.Protos.Common.V1.

Dependencies

  • DcsvIo.D2.Result — result-core (D2Result, InputError, TKMessage surface)
  • DcsvIo.D2.ErrorCodes.CategoryErrorCategory, ErrorCategoryWire
  • DcsvIo.D2.UtilitiesFalsey() null-guard
  • DcsvIo.D2.I18n.AbstractionsTKMessage ctor (InternalsVisibleTo)
  • Google.Protobuf — proto runtime
  • Grpc.Net.ClientAsyncUnaryCall<T>, RpcException
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 106 7/17/2026
0.1.0 102 7/17/2026