Skip to content

Commit

Permalink
Merge pull request #218 from dlcs/fix/niceSerializationError
Browse files Browse the repository at this point in the history
Fixing serialization error to provide a nicer error
  • Loading branch information
JackLewis-digirati authored Jan 16, 2025
2 parents 0f81fe6 + b8b493c commit 751c160
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -506,4 +506,43 @@ public async Task PutFlatId_Update_IgnoresPaintedResources_WhenItemsAndPaintedRe
.Be("https://iiif.example/manifestFromItems.json");
presentationManifest.Items.Count.Should().Be(1);
}

[Fact]
public async Task? CreateManifest_ReturnsNiceError_WhenDeserializationError()
{
// Arrange
var slug = nameof(CreateManifest_ReturnsNiceError_WhenDeserializationError);
var manifest = $$"""
{
"slug": "{{slug}}",
"parent": "https://presentation-api.dlcs.digirati.io/52/collections/root",
"type": "Manifest",
"label": {
"en": [
"Example Manifest"
]
},
"behavior": [
"paged"
],
"items": [
{
"my_external_manifest": "https://digirati.io/resources/cheese.json"
}
]
}
""";

var requestMessage =
HttpRequestMessageBuilder.GetPrivateRequest(HttpMethod.Put, $"{Customer}/manifests/brokenManifest",
manifest);

// Act
var response = await httpClient.AsCustomer().SendAsync(requestMessage);

// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var errorResponse = await response.ReadAsPresentationResponseAsync<Error>();
errorResponse!.Detail.Should().Be("Could not deserialize manifest");
}
}
12 changes: 7 additions & 5 deletions src/IIIFPresentation/API/Features/Manifest/ManifestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using API.Auth;
using API.Features.Manifest.Requests;
using API.Features.Manifest.Validators;
using API.Features.Storage.Helpers;
using API.Infrastructure;
using API.Infrastructure.Helpers;
using API.Infrastructure.Requests;
Expand All @@ -12,6 +13,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Models.API.Collection;
using Models.API.Manifest;

namespace API.Features.Manifest;
Expand Down Expand Up @@ -100,21 +102,21 @@ private async Task<IActionResult> ManifestUpsert<T, TEnum>(
if (!Request.HasShowExtraHeader()) return this.Forbidden();

var rawRequestBody = await Request.GetRawRequestBodyAsync(cancellationToken);
var presentationManifest = await rawRequestBody.ToPresentation<PresentationManifest>();
var presentationManifest = await rawRequestBody.TryDeserializePresentation<PresentationManifest>();

if (presentationManifest == null)
if (presentationManifest.Error)
{
return this.PresentationProblem("Could not deserialize manifest", null, (int) HttpStatusCode.BadRequest,
"Deserialization Error");
}

var validation = await validator.ValidateAsync(presentationManifest, cancellationToken);
var validation = await validator.ValidateAsync(presentationManifest.ConvertedIIIF!, cancellationToken);
if (!validation.IsValid)
{
return this.ValidationFailed(validation);
}

return await HandleUpsert(requestFactory(presentationManifest, rawRequestBody), instance, errorTitle,
return await HandleUpsert(requestFactory(presentationManifest.ConvertedIIIF!, rawRequestBody), instance, errorTitle,
cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ private async Task<DeserializeValidationResult<PresentationCollection>> Deserial

var rawRequestBody = await Request.GetRawRequestBodyAsync();

var deserializedCollection = await rawRequestBody.TryDeserializePresentationCollection();
var deserializedCollection =
await rawRequestBody.TryDeserializePresentation<PresentationCollection>();
if (deserializedCollection.Error)
{
return DeserializeValidationResult<PresentationCollection>.Failure(PresentationUnableToSerialize());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Core.IIIF;
using IIIF;
using IIIF.Serialisation;
using Models.API;
using Models.API.Collection;

namespace API.Features.Storage.Helpers;
Expand Down Expand Up @@ -35,19 +36,20 @@ public static TryConvertIIIFResult<T> ConvertCollectionToIIIF<T>(this string req
/// </summary>
/// <param name="requestBody">The raw request body to convert</param>
/// <returns>A result containing the deserialized collection, or a failure</returns>
public static async Task<TryConvertIIIFResult<PresentationCollection>> TryDeserializePresentationCollection(this string requestBody)
public static async Task<TryConvertIIIFResult<T>> TryDeserializePresentation<T>(this string requestBody)
where T : JsonLdBase, new()
{
try
{
var collection = await requestBody.ToPresentation<PresentationCollection>();
var collection = await requestBody.ToPresentation<T>();

return collection == null
? TryConvertIIIFResult<PresentationCollection>.Failure()
: TryConvertIIIFResult<PresentationCollection>.Success(collection);
? TryConvertIIIFResult<T>.Failure()
: TryConvertIIIFResult<T>.Success(collection);
}
catch (Exception)
{
return TryConvertIIIFResult<PresentationCollection>.Failure();
return TryConvertIIIFResult<T>.Failure();
}
}
}
}

0 comments on commit 751c160

Please sign in to comment.