WabiSabi protocol violations error handling
ADD
WalletWasabi.Backend/Filters/ExceptionTranslateFilter.cs
+using System;
+using System.Net;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using WalletWasabi.WabiSabi.Backend.Models;
+using WalletWasabi.WabiSabi.Models;
+
+namespace WalletWasabi.Backend.Filters
+{
+ public class ExceptionTranslateAttribute : ExceptionFilterAttribute
+ {
+ public override void OnException(ExceptionContext context)
+ {
+ var exception = context.Exception.InnerException ?? context.Exception;
+ var exceptionMessage = exception.Message;
+
+ context.Result = new JsonResult(
+ exception switch
+ {
+ WabiSabiProtocolException e => new Error(
+ Type: "wabisabi-protocol-violation",
+ ErrorCode: e.ErrorCode.ToString(),
+ Description: e.Message),
+ Exception e => new Error(
+ Type: "unknown",
+ ErrorCode: "0",
+ Description: e.Message)
+ }
+ )
+ {
+ StatusCode = (int)HttpStatusCode.InternalServerError
+ };
+ }
+ }
+}
\ No newline at end of file

MODIFY
WalletWasabi/Tor/Http/Extensions/HttpResponseMessageExtensions.cs
WalletWasabi/Tor/Http/Extensions/HttpResponseMessageExtensions.cs
+using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Newtonsoft.Json;
using WalletWasabi.Tor.Http.Helpers;
using WalletWasabi.Tor.Http.Models;
+using WalletWasabi.WabiSabi.Backend.Models;
+using WalletWasabi.WabiSabi.Models;
namespace WalletWasabi.Tor.Http.Extensions
{
@@ -61,6 +65,20 @@ namespace WalletWasabi.Tor.Http.Extensions
if (me.Content is { })
{
var contentString = await me.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
+ var error = JsonConvert.DeserializeObject<Error>(contentString);
+ var innerException = error switch
+ {
+ { Type: "wabisabi-protocol-violation"} => Enum.TryParse<WabiSabiProtocolErrorCode>(error.ErrorCode, out var code)
+ ? new WabiSabiProtocolException(code, error.Description)
+ : new NotSupportedException($"Received wabisabi protocol exception with unknown '{error.ErrorCode}' error code.\n\tDescription: '{error.Description}'."),
+ { Type: "unknown"} => new Exception(error.Description),
+ _ => null
+ };
+
+ if (innerException is not null)
+ {
+ throw new HttpRequestException("Remote coordinator responded with an error.", innerException, me.StatusCode);
+ }
// Remove " from beginning and end to ensure backwards compatibility and it's kindof trash, too.
if (contentString.Count(f => f == '"') <= 2)

MODIFY
WalletWasabi/WabiSabi/Backend/Models/WabiSabiProtocolException.cs
WalletWasabi/WabiSabi/Backend/Models/WabiSabiProtocolException.cs
@@ -12,11 +12,22 @@ namespace WalletWasabi.WabiSabi.Backend.Models
public class WabiSabiProtocolException : Exception
{
public WabiSabiProtocolException(WabiSabiProtocolErrorCode errorCode, string? message = null, Exception? innerException = null)
- : base(message, innerException)
+ : base(message ?? ErrorCodeDescription(errorCode), innerException)
{
ErrorCode = errorCode;
}
public WabiSabiProtocolErrorCode ErrorCode { get; }
+
+ private static string ErrorCodeDescription(WabiSabiProtocolErrorCode errorCode)
+ {
+ var enumName = Enum.GetName<WabiSabiProtocolErrorCode>(errorCode) ?? "";
+ var errorDescription = string.Join(
+ "",
+ enumName.Select((c, i) => i > 0 && char.IsUpper(c)
+ ? " " + char.ToLowerInvariant(c)
+ : "" + c));
+ return errorDescription;
+ }
}
}

ADD
WalletWasabi/WabiSabi/Models/Error.cs
+namespace WalletWasabi.WabiSabi.Models
+{
+ public record Error(
+ string Type,
+ string ErrorCode,
+ string Description
+ );
+}
\ No newline at end of file

WabiSabi protocol violations error handling