private static async ValueTask <IReadOnlyList <Document> > DeserializeArrayAsync(Stream utf8JsonStream, int defaultBufferSize, CancellationToken cancellationToken = default) { var result = await EntityDdbJsonReader.ReadAsync <IReadOnlyList <Document> >(utf8JsonStream, DocumentArrayClassInfo, EmptyMetadata, false, defaultBufferSize, cancellationToken) .ConfigureAwait(false); return(result.Value ?? throw new InvalidOperationException("JSON does not contain a valid document.")); }
private async ValueTask <TResult> ReadAsync <TResult>(HttpResponseMessage response, CancellationToken cancellationToken = default) where TResult : class { await using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); var expectedCrc = GetExpectedCrc(response); var classInfo = Config.Metadata.GetOrAddClassInfo(typeof(TResult), typeof(JsonObjectDdbConverter <TResult>)); var result = await EntityDdbJsonReader.ReadAsync <TResult>(responseStream, classInfo, Config.Metadata, expectedCrc.HasValue, cancellationToken : cancellationToken).ConfigureAwait(false); if (expectedCrc.HasValue && expectedCrc.Value != result.Crc) { throw new ChecksumMismatchException(); } return(result.Value !); }
public static async ValueTask ProcessErrorAsync(DynamoDbContextMetadata metadata, HttpResponseMessage response, CancellationToken cancellationToken = default) { try { await using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { throw new ServiceUnavailableException("DynamoDB is currently unavailable. (This should be a temporary state.)"); } var recyclableStream = DynamoDbHttpContent.MemoryStreamManager.GetStream(); try { await responseStream.CopyToAsync(recyclableStream, cancellationToken).ConfigureAwait(false); recyclableStream.Position = 0; var error = await JsonSerializer.DeserializeAsync <Error>(recyclableStream, SerializerOptions, cancellationToken).ConfigureAwait(false); recyclableStream.Position = 0; switch (response.StatusCode) { case HttpStatusCode.BadRequest: var type = error.Type; var exceptionStart = error.Type?.LastIndexOf('#') ?? -1; if (exceptionStart != -1) { type = error.Type !.Substring(exceptionStart + 1); } if (type == "TransactionCanceledException") { var classInfo = metadata.GetOrAddClassInfo(typeof(TransactionCancelledResponse), typeof(JsonObjectDdbConverter <TransactionCancelledResponse>)); var transactionCancelledResponse = await EntityDdbJsonReader .ReadAsync <TransactionCancelledResponse>(recyclableStream, classInfo, metadata, false, cancellationToken : cancellationToken) .ConfigureAwait(false); throw new TransactionCanceledException(transactionCancelledResponse.Value !.CancellationReasons, error.Message); } throw type switch { "AccessDeniedException" => new AccessDeniedException(error.Message), "ConditionalCheckFailedException" => new ConditionalCheckFailedException(error.Message), "IncompleteSignatureException" => new IncompleteSignatureException(error.Message), "ItemCollectionSizeLimitExceededException" => new ItemCollectionSizeLimitExceededException(error.Message), "LimitExceededException" => new LimitExceededException(error.Message), "MissingAuthenticationTokenException" => new MissingAuthenticationTokenException(error.Message), "ProvisionedThroughputExceededException" => new ProvisionedThroughputExceededException(error.Message), "RequestLimitExceeded" => new RequestLimitExceededException(error.Message), "ResourceInUseException" => new ResourceInUseException(error.Message), "ResourceNotFoundException" => new ResourceNotFoundException(error.Message), "ThrottlingException" => new ThrottlingException(error.Message), "UnrecognizedClientException" => new UnrecognizedClientException(error.Message), "ValidationException" => new ValidationException(error.Message), "IdempotentParameterMismatchException" => new IdempotentParameterMismatchException(error.Message), "TransactionInProgressException" => new TransactionInProgressException(error.Message), _ => new DdbException(error.Message ?? type ?? string.Empty) }; case HttpStatusCode.InternalServerError: throw new InternalServerErrorException(error.Message); default: throw new DdbException(error.Message); } } finally { await recyclableStream.DisposeAsync().ConfigureAwait(false); } } finally { response.Dispose(); } }