diff --git a/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/_index.md b/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/_index.md index f03bf676..4a2f065d 100644 --- a/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/_index.md +++ b/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/_index.md @@ -1,7 +1,7 @@ --- type: docs -title: "Error Handling .NET SDK" +title: "Error Handling in the Dapr .NET SDK" linkTitle: "Error handling" weight: 50000 -description: Learn about Dapr error handling in the .NET SDK. +description: Learn about error handling in the Dapr.NET SDK. --- \ No newline at end of file diff --git a/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/dotnet-richer-error-model.md b/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/dotnet-richer-error-model.md index 5cfea00f..cff21ac4 100644 --- a/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/dotnet-richer-error-model.md +++ b/daprdocs/content/en/dotnet-sdk-docs/dotnet-error-handling/dotnet-richer-error-model.md @@ -1,7 +1,138 @@ --- type: docs -title: "Richer Error Model in the .NET SDK" +title: "Richer Error Model in the Dapr .NET SDK" linkTitle: "Richer error model" weight: 59000 description: Learn how to use the richer error model in the .NET SDK. ---- \ No newline at end of file +--- + +The Dapr .NET SDK supports the richer error model, implemented by the Dapr runtime. This model provides a way for applications to enrich their errors with added context, +allowing consumers of the application to better understand the issue and resolve faster. You can read more about the richer error model [here](https://google.aip.dev/193), and you +can find the Dapr proto file implementing these errors [here](https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto"). + +The Dapr .NET SDK implements all details supported by the Dapr runtime, implemented in the `Dapr.Common.Exceptions` namespace, and is accessible through +the `DaprException` extension method `TryGetExtendedErrorInfo`. Currently this detail extraction is only supported for +`RpcException`'s where the details are present. + +```csharp +// Example usage of ExtendedErrorInfo + +try +{ + // Perform some action with the Dapr client that throws a DaprException. +} +catch (DaprException daprEx) +{ + if (daprEx.TryGetExtendedErrorInfo(out DaprExtendedErrorInfo errorInfo) + { + Console.WriteLine(errorInfo.Code); + Console.WriteLine(errorInfo.Message); + + foreach (DaprExtendedErrorDetail detail in errorInfo.Details) + { + Console.WriteLine(detail.ErrorType); + switch (detail.ErrorType) + case ExtendedErrorType.ErrorInfo: + Console.WriteLine(detail.Reason); + Console.WriteLine(detail.Domain); + } + } +} +``` + +## DaprExtendedErrorInfo + +Contains `Code` (the status code) and `Message` (the error message) associated with the error, parsed from an inner `RpcException`. +Also contains a collection of `DaprExtendedErrorDetails` parsed from the details in the exception. + +## DaprExtendedErrorDetail + +All details implement the abstract `DaprExtendedErrorDetail` and have an associated `DaprExtendedErrorType`. + +1. [RetryInfo](#retryinfo) + +2. [DebugInfo](#debuginfo) + +3. [QuotaFailure](#quotafailure) + +4. [PreconditionFailure](#preconditionfailure) + +5. [RequestInfo](#requestinfo) + +6. [LocalizedMessage](#localizedmessage) + +7. [BadRequest](#badrequest) + +8. [ErrorInfo](#errorinfo) + +9. [Help](#help) + +10. [ResourceInfo](#resourceinfo) + +11. [Unknown](#unknown) + +## RetryInfo + +Information telling the client how long to wait before they should retry. Provides a `DaprRetryDelay` with the properties +`Second` (offset in seconds) and `Nano` (offset in nanoseconds). + +## DebugInfo + +Debugging information offered by the server. Contains `StackEntries` (a collection of strings containing the stack trace), and +`Detail` (further debugging information). + +## QuotaFailure + +Information relating to some quota that may have been reach, such as a daily usage limit on an API. It has one property `Violations`, +a collection of `DaprQuotaFailureViolation`, which each contain a `Subject` (the subject of the request) and `Description` (further information regarding the failure). + +## PreconditionFailure + +Information informing the client that some required precondition was not met. Has one property `Violations`, a collection of +`DaprPreconditionFailureViolation`, which each has `Subject` (subject where the precondition failure occured e.g. "Azure"), `Type` (representation of the precondition type e.g. "TermsOfService"), and `Description` (further description e.g. "ToS must be accepted."). + +## RequestInfo + +Information returned by the server that can be used by the server to identify the clients request. Contains +`RequestId` and `ServingData` properties, `RequestId` being some string (such as a UID) the server can interpret, +and `ServingData` being some arbitrary data that made up part of the request. + +## LocalizedMessage + +Contains a localized message, along with the locale of the message. Contains `Locale` (the locale e.g. "en-US") and `Message` (the localized message). + +## BadRequest + +Describes a bad request field. Contains collection of `DaprBadRequestDetailFieldViolation`, which each has `Field` (the offending field in request e.g. 'first_name') and +`Description` (further information detailing the reason e.g. "first_name cannot contain special characters"). + +## ErrorInfo + +Details the cause of an error. Contains three properties, `Reason` (the reason for the error, which should take the form of UPPER_SNAKE_CASE e.g. DAPR_INVALID_KEY), +`Domain` (domain the error belongs to e.g. 'dapr.io'), and `Metadata`, a key value based collection of futher information. + +## Help + +Provides resources for the client to perform further research into the issue. Contains a collection of `DaprHelpDetailLink`, +which provides `Url` (a url to help or documentation), and `Description` (a description of what the link provides). + +## ResourceInfo + +Provides information relating to an accessed resource. Provides three properties `ResourceType` (type of the resource being access e.g. "Azure service bus"), +`ResourceName` (The name of the resource e.g. "my-configured-service-bus"), `Owner` (the owner of the resource e.g. "subscriptionowner@dapr.io"), +and `Description` (further information on the resource relating to the error e.g. "missing permissions to use this resource"). + +## Unknown + +Returned when the detail type url cannot be mapped to the correct `DaprExtendedErrorDetail` implementation. +Provides one property `TypeUrl` (the type url that could not be parsed e.g. "type.googleapis.com/Google.rpc.UnrecognizedType"). + + + + + + + + + + diff --git a/src/Dapr.Common/Exceptions/DaprExceptionExtensions.cs b/src/Dapr.Common/Exceptions/DaprExceptionExtensions.cs index 3e2f4514..2f195d69 100644 --- a/src/Dapr.Common/Exceptions/DaprExceptionExtensions.cs +++ b/src/Dapr.Common/Exceptions/DaprExceptionExtensions.cs @@ -24,7 +24,7 @@ public static class DaprExceptionExtensions /// /// Attempt to retrieve from . /// - /// A Dapr exception.. + /// A Dapr exception. . /// out if parsable from inner exception, null otherwise. /// True if extended info is available, false otherwise. public static bool TryGetExtendedErrorInfo(this DaprException exception, [NotNullWhen(true)] out DaprExtendedErrorInfo? daprExtendedErrorInfo) diff --git a/src/Dapr.Common/Exceptions/DaprExtendedErrorConstants.cs b/src/Dapr.Common/Exceptions/DaprExtendedErrorConstants.cs index 514aecc3..bda382fc 100644 --- a/src/Dapr.Common/Exceptions/DaprExtendedErrorConstants.cs +++ b/src/Dapr.Common/Exceptions/DaprExtendedErrorConstants.cs @@ -2,7 +2,7 @@ { internal class DaprExtendedErrorConstants { - public const string DaprErrorDetailTypeUrl = "type.googleapis.com/"; + public const string ErrorDetailTypeUrl = "type.googleapis.com/"; public const string GrpcDetails = "grpc-status-details-bin"; } diff --git a/src/Dapr.Common/Exceptions/ExtendedErrorDetailFactory.cs b/src/Dapr.Common/Exceptions/ExtendedErrorDetailFactory.cs index 00561602..3d5654e4 100644 --- a/src/Dapr.Common/Exceptions/ExtendedErrorDetailFactory.cs +++ b/src/Dapr.Common/Exceptions/ExtendedErrorDetailFactory.cs @@ -5,11 +5,11 @@ namespace Dapr.Common.Exceptions { /// - /// factory class. + /// factory. /// internal static class ExtendedErrorDetailFactory { - private const string DaprErrorTypeUrl = DaprExtendedErrorConstants.DaprErrorDetailTypeUrl; + private const string DaprErrorTypeUrl = DaprExtendedErrorConstants.ErrorDetailTypeUrl; private static Dictionary> extendedErrorTypeMapping = new() @@ -29,16 +29,16 @@ internal static class ExtendedErrorDetailFactory /// /// Create a new from an instance of . /// - /// The detail metadata to create the error detail from. + /// The serialized detail message to create the error detail from. /// A new instance of - internal static DaprExtendedErrorDetail CreateErrorDetail(Any metadata) + internal static DaprExtendedErrorDetail CreateErrorDetail(Any message) { - if (!extendedErrorTypeMapping.TryGetValue(metadata.TypeUrl, out var create)) + if (!extendedErrorTypeMapping.TryGetValue(message.TypeUrl, out var create)) { - return new DaprUnknownDetail(metadata.TypeUrl); + return new DaprUnknownDetail(message.TypeUrl); } - return create.Invoke(metadata.Value); + return create.Invoke(message.Value); } private static DaprRetryInfoDetail ToDaprRetryInfoDetail(ByteString data)