Refactor MaybeThrowGraphqlException to throw AggregateException with all GraphQL errors (#169)

* first pass

* Updated tests

* Removed path from message
This commit is contained in:
Jedd Morgan
2024-11-19 13:22:52 +00:00
committed by GitHub
parent af35edf0a2
commit 39dcc5da0b
20 changed files with 458 additions and 419 deletions
@@ -1,7 +1,6 @@
using GraphQL;
using GraphQL.Client.Http;
using Speckle.Sdk.Api.GraphQL.Models.Responses;
using Speckle.Sdk.Common;
namespace Speckle.Sdk.Api.GraphQL;
@@ -10,46 +9,51 @@ public static class GraphQLHttpClientExtensions
/// <summary>
/// Gets the version of the current server. Useful for guarding against unsupported api calls on newer or older servers.
/// </summary>
/// <param name="cancellationToken">[Optional] defaults to an empty cancellation token</param>
/// <returns><see cref="Version"/> object excluding any strings (eg "2.7.2-alpha.6995" becomes "2.7.2.6995")</returns>
/// <exception cref="SpeckleGraphQLException{ServerInfoResponse}"></exception>
/// <remarks>
/// Expects the response to either be<br/>
/// - 1. The literal string <c>dev</c>, which will return <c>999.999.999</c><br/>
/// - 2. A 3 numeral semver (anything after the first <c>-</c> character will be ignored)<br/>
/// </remarks>
/// <param name="cancellationToken"></param>
/// <returns>A 3 numeral <see cref="Version"/> object (e.g. <c>2.21.3.alpha123</c> becomes <c>2.21.3</c>)</returns>
/// <exception cref="AggregateException"><inheritdoc cref="GraphQLErrorHandler.EnsureGraphQLSuccess(IGraphQLResponse)"/></exception>
/// <exception cref="FormatException">Server responded with a server version, but it was not in an expected format</exception>
public static async Task<System.Version> GetServerVersion(
this GraphQLHttpClient client,
CancellationToken cancellationToken = default
)
{
var request = new GraphQLRequest
{
Query =
@"query Server {
serverInfo {
version
}
}",
};
//lang=graphql
const string QUERY = """
query Server {
data:serverInfo {
data:version
}
}
""";
var request = new GraphQLRequest { Query = QUERY };
var response = await client.SendQueryAsync<ServerInfoResponse>(request, cancellationToken).ConfigureAwait(false);
var response = await client
.SendQueryAsync<RequiredResponse<RequiredResponse<string>>>(request, cancellationToken)
.ConfigureAwait(false);
if (response.Errors != null)
response.EnsureGraphQLSuccess();
string versionString = response.Data.data.data;
if (versionString == "dev")
{
throw new SpeckleGraphQLException<ServerInfoResponse>(
$"Query {nameof(GetServerVersion)} failed",
request,
response
);
return new Version(999, 999, 999);
}
if (string.IsNullOrWhiteSpace(response.Data.serverInfo.version))
{
throw new SpeckleGraphQLException<ServerInfoResponse>(
$"Query {nameof(GetServerVersion)} did not provide a valid server version",
request,
response
);
}
string? semverString = versionString.Split('-').First();
return response.Data.serverInfo.version == "dev"
? new System.Version(999, 999, 999)
: new System.Version(response.Data.serverInfo.version.NotNull().Split('-').First());
if (Version.TryParse(semverString!, out Version? semver))
{
return semver;
}
else
{
throw new FormatException($"Server responded with an invalid semver string \"{semverString}\"");
}
}
}