using Grpc.Core; using Mishima.Nexus.Wire.V1; using Robotico.Result.Errors; namespace Robotico.Nexus.Client; /// Maps wire envelopes and gRPC failures to . internal static class NexusWireStatus { private const string OkCode = "OK"; /// Returns success when reports OK; otherwise a coded error. internal static Robotico.Result.Result ToResult(NexusStatus? status) { if (status is null) { return Robotico.Result.Result.Error(NexusErrors.Error("Nexus response is missing a status envelope.", NexusErrors.WireFailed)); } if (string.Equals(status.Code, OkCode, StringComparison.Ordinal)) { return Robotico.Result.Result.Success(); } string code = string.IsNullOrWhiteSpace(status.Code) ? NexusErrors.WireFailed : status.Code; string message = string.IsNullOrWhiteSpace(status.Message) ? "Nexus call failed." : status.Message; return Robotico.Result.Result.Error(NexusErrors.Error(message, code)); } /// Maps status to , carrying on success. internal static Robotico.Result.Result ToResult(NexusStatus? status, T value) { Robotico.Result.Result plain = ToResult(status); return plain.IsError(out IError? error) ? Robotico.Result.Result.Error(error!) : Robotico.Result.Result.Success(value); } /// True when reports OK. internal static bool IsOk(NexusStatus? status) => status is not null && string.Equals(status.Code, OkCode, StringComparison.Ordinal); /// Maps a failed gRPC call into a coded . internal static IError FromException(RpcException exception) { string code = exception.StatusCode switch { StatusCode.OK => NexusErrors.WireFailed, StatusCode.Cancelled => NexusErrors.Unavailable, StatusCode.Unknown => NexusErrors.WireFailed, StatusCode.InvalidArgument => NexusErrors.InvalidArgument, StatusCode.DeadlineExceeded => NexusErrors.Unavailable, StatusCode.NotFound => NexusErrors.NotFound, StatusCode.AlreadyExists => NexusErrors.AlreadyExists, StatusCode.PermissionDenied => NexusErrors.WireFailed, StatusCode.ResourceExhausted => NexusErrors.Unavailable, StatusCode.FailedPrecondition => NexusErrors.InvalidArgument, StatusCode.Aborted => NexusErrors.WireFailed, StatusCode.OutOfRange => NexusErrors.InvalidArgument, StatusCode.Unimplemented => NexusErrors.WireFailed, StatusCode.Internal => NexusErrors.WireFailed, StatusCode.Unavailable => NexusErrors.Unavailable, StatusCode.DataLoss => NexusErrors.WireFailed, StatusCode.Unauthenticated => NexusErrors.WireFailed, _ => NexusErrors.WireFailed, }; string detail = string.IsNullOrWhiteSpace(exception.Status.Detail) ? exception.Message : exception.Status.Detail; return NexusErrors.Error($"gRPC call failed ({exception.StatusCode}): {detail}", code); } }