Browse Source

Improved validation handling.

pull/235/head
Sebastian Stehle 8 years ago
parent
commit
b6282793a6
  1. 14
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs
  2. 59
      src/Squidex.Infrastructure/ValidationException.cs
  3. 2
      src/Squidex/Pipeline/ApiExceptionFilterAttribute.cs
  4. 54
      tests/Squidex.Infrastructure.Tests/ValidationExceptionTests.cs

14
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs

@ -87,6 +87,8 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
throw new ValidationException("This odata operation is not supported.");
}
try
{
var contentItems = Collection.Find(filter).Take(odataQuery).Skip(odataQuery).Sort(odataQuery, schema.SchemaDef).ToListAsync();
var contentCount = Collection.Find(filter).CountAsync();
@ -99,6 +101,18 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
return ResultList.Create<IContentEntity>(contentItems.Result, contentCount.Result);
}
catch (MongoQueryException ex)
{
if (ex.Message.Contains("17406"))
{
throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items.");
}
else
{
throw;
}
}
}
public async Task<IResultList<IContentEntity>> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet<Guid> ids)
{

59
src/Squidex.Infrastructure/ValidationException.cs

@ -9,11 +9,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace Squidex.Infrastructure
{
[Serializable]
public class ValidationException : Exception
public class ValidationException : DomainException
{
private static readonly List<ValidationError> FallbackErrors = new List<ValidationError>();
private readonly IReadOnlyList<ValidationError> errors;
@ -23,27 +24,29 @@ namespace Squidex.Infrastructure
get { return errors; }
}
public ValidationException(string message, params ValidationError[] errors)
: base(message)
public string Summary { get; }
public ValidationException(string summary, params ValidationError[] errors)
: this(summary, null, errors?.ToList())
{
this.errors = errors != null ? errors.ToList() : FallbackErrors;
}
public ValidationException(string message, IReadOnlyList<ValidationError> errors)
: base(message)
public ValidationException(string summary, IReadOnlyList<ValidationError> errors)
: this(summary, null, errors)
{
this.errors = errors ?? FallbackErrors;
}
public ValidationException(string message, Exception inner, params ValidationError[] errors)
: base(message, inner)
public ValidationException(string summary, Exception inner, params ValidationError[] errors)
: this(summary, null, errors?.ToList())
{
this.errors = errors != null ? errors.ToList() : FallbackErrors;
}
public ValidationException(string message, Exception inner, IReadOnlyList<ValidationError> errors)
: base(message, inner)
public ValidationException(string summary, Exception inner, IReadOnlyList<ValidationError> errors)
: base(FormatMessage(summary, errors), inner)
{
Summary = summary;
this.errors = errors ?? FallbackErrors;
}
@ -52,9 +55,39 @@ namespace Squidex.Infrastructure
{
}
public override string ToString()
private static string FormatMessage(string summary, IReadOnlyList<ValidationError> errors)
{
var sb = new StringBuilder();
sb.Append(summary.TrimEnd(' ', '.', ':'));
if (errors?.Count > 0)
{
sb.Append(": ");
for (var i = 0; i < errors.Count; i++)
{
var error = errors[i].Message;
sb.Append(error);
if (!error.EndsWith(".", StringComparison.OrdinalIgnoreCase))
{
return string.Join(" ", Enumerable.Repeat(Message, 1).Union(Errors.Select(x => x.Message)));
sb.Append(".");
}
if (i < errors.Count - 1)
{
sb.Append(" ");
}
}
}
else
{
sb.Append(".");
}
return sb.ToString();
}
}
}

2
src/Squidex/Pipeline/ApiExceptionFilterAttribute.cs

@ -54,7 +54,7 @@ namespace Squidex.Pipeline
private static IActionResult OnValidationException(ValidationException ex)
{
return ErrorResult(400, new ErrorDto { Message = ex.Message, Details = ex.Errors.Select(e => e.Message).ToArray() });
return ErrorResult(400, new ErrorDto { Message = ex.Summary, Details = ex.Errors.Select(e => e.Message).ToArray() });
}
private static IActionResult ErrorResult(int statusCode, ErrorDto error)

54
tests/Squidex.Infrastructure.Tests/ValidationExceptionTests.cs

@ -0,0 +1,54 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Xunit;
namespace Squidex.Infrastructure
{
public class ValidationExceptionTests
{
[Fact]
public void Should_format_message_from_summary()
{
var ex = new ValidationException("Summary.");
Assert.Equal("Summary.", ex.Message);
}
[Fact]
public void Should_append_dot_to_summary()
{
var ex = new ValidationException("Summary");
Assert.Equal("Summary.", ex.Message);
}
[Fact]
public void Should_format_message_from_errors()
{
var ex = new ValidationException("Summary", new ValidationError("Error1."), new ValidationError("Error2."));
Assert.Equal("Summary: Error1. Error2.", ex.Message);
}
[Fact]
public void Should_not_add_colon_twice()
{
var ex = new ValidationException("Summary:", new ValidationError("Error1."), new ValidationError("Error2."));
Assert.Equal("Summary: Error1. Error2.", ex.Message);
}
[Fact]
public void Should_append_dots_to_errors()
{
var ex = new ValidationException("Summary", new ValidationError("Error1"), new ValidationError("Error2"));
Assert.Equal("Summary: Error1. Error2.", ex.Message);
}
}
}
Loading…
Cancel
Save