| File: NativeCapabilityResult.cs | Web Access |
| Project: src\src\Aspire.Hosting.Native.Client\Aspire.Hosting.Native.Client.csproj (Aspire.Hosting.Native.Client) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json; namespace Aspire.Hosting.Native.Client; /// <summary>Validates ATS result failures before generated result deserialization.</summary> internal static class NativeCapabilityResult { public static JsonElement Parse(JsonElement result) { // ATS failures are successful JSON-RPC results: // {"result":{"$error":{"code":"HANDLE_NOT_FOUND","message":"..."}}}. // Missing, null or non-string failure fields are protocol errors, not // capability failures, and must never expose their raw payload in diagnostics. if (result.ValueKind == JsonValueKind.Object && result.TryGetProperty("$error", out var error)) { var failure = ParseFailure(result, error); throw new NativeCapabilityException(failure.Code, failure.Message); } return result; } private static CapabilityFailure ParseFailure(JsonElement result, JsonElement error) { if (result.EnumerateObject().Count() != 1 || error.ValueKind != JsonValueKind.Object || error.EnumerateObject().Count() != 2 || !error.TryGetProperty("code", out var code) || code.ValueKind != JsonValueKind.String || code.GetString() is not { Length: > 0 } codeValue || !error.TryGetProperty("message", out var message) || message.ValueKind != JsonValueKind.String || message.GetString() is not { } messageValue) { throw new InvalidDataException("The native capability failure response is malformed."); } return new CapabilityFailure(codeValue, messageValue); } private readonly record struct CapabilityFailure(string Code, string Message); }