dotnet/src/Azure.Iot.Operations.Services/StateStore/StateStoreOperationException.cs (78 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Azure.Iot.Operations.Services.StateStore { // <summary> // Enum representing the reason for a state store implementation exception. // </summary> public enum StateStoreErrorKind { // <summary> // Error occurred in the AIO protocol // </summary> AIOProtocolError, // <summary> // Error occurred from the State Store Service. // </summary> ServiceError, // <summary> // Key length must not be zero. // </summary> KeyLengthZero, // <summary> // Error occurred during serialization of a request. // </summary> SerializationError, // <summary> // Argument provided for a request was invalid. // </summary> InvalidArgument, // <summary> // Payload of the response does not match the expected type for the request. // </summary> UnexpectedPayload } // <summary> // Enum representing the reason for a state store service exception. // </summary> public enum ServiceError { // <summary> // The requested timestamp is too far in the future; ensure that the client and broker system clocks are synchronized. // </summary> TimestampSkew, // <summary> // A fencing token is required for this request. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> MissingFencingToken, // <summary> // The requested fencing token timestamp is too far in the future; ensure that the client and broker system clocks are synchronized. // </summary> FencingTokenSkew, // <summary> // The requested fencing token is a lower version than the fencing token protecting the resource. // </summary> FencingTokenLowerVersion, // <summary> // The quota has been exceeded. // </summary> KeyQuotaExceeded, // <summary> // Syntax error. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> SyntaxError, // <summary> // Not authorized. // </summary> NotAuthorized, // <summary> // Unknown command. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> UnknownCommand, // <summary> // Wrong number of arguments. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> WrongNumberOfArguments, // <summary> // Missing timestamp. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> TimestampMissing, // <summary> // Malformed timestamp. // </summary> // <remarks> // This error code should not happen when using this library as it will always format requests correctly. // </remarks> TimestampMalformed, // <summary> // The key length is zero. // </summary> KeyLengthZero, // <summary> // An unknown error was received from the State Store Service. // </summary> Unknown } public class StateStoreOperationException : Exception { public ServiceError Reason { get; } private static readonly Dictionary<string, ServiceError> ErrorMessages = new Dictionary<string, ServiceError> { { "the request timestamp is too far in the future; ensure that the client and broker system clocks are synchronized", ServiceError.TimestampSkew }, { "a fencing token is required for this request", ServiceError.MissingFencingToken }, { "the request fencing token timestamp is too far in the future; ensure that the client and broker system clocks are synchronized", ServiceError.FencingTokenSkew }, { "the request fencing token is a lower version than the fencing token protecting the resource", ServiceError.FencingTokenLowerVersion }, { "the quota has been exceeded", ServiceError.KeyQuotaExceeded }, { "syntax error", ServiceError.SyntaxError }, { "not authorized", ServiceError.NotAuthorized }, { "unknown command", ServiceError.UnknownCommand }, { "wrong number of arguments", ServiceError.WrongNumberOfArguments }, { "missing timestamp", ServiceError.TimestampMissing }, { "malformed timestamp", ServiceError.TimestampMalformed }, { "the key length is zero", ServiceError.KeyLengthZero } }; public StateStoreOperationException(string message, Exception innerException, ServiceError reason) : base(message, innerException) { Reason = reason; } public StateStoreOperationException(string message, Exception innerException) : base(FormatMessage(message, ReasonFromMessage(message).Item1), innerException) { Reason = ReasonFromMessage(message).Item1; } public StateStoreOperationException(string message) : base(FormatMessage(message, ReasonFromMessage(message).Item1)) { Reason = ReasonFromMessage(message).Item1; } private static (ServiceError, string) ReasonFromMessage(string message) { foreach (var errorMessage in ErrorMessages) { if (message.Contains(errorMessage.Key)) { return (errorMessage.Value, message); } } return (ServiceError.Unknown, message); } private static string FormatMessage(string originalMessage, ServiceError reason) { return reason == ServiceError.Unknown ? $"Unknown error: {originalMessage}" : originalMessage; } } }