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."); 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 contentItems = Collection.Find(filter).Take(odataQuery).Skip(odataQuery).Sort(odataQuery, schema.SchemaDef).ToListAsync();
var contentCount = Collection.Find(filter).CountAsync(); 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); 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) 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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text;
namespace Squidex.Infrastructure namespace Squidex.Infrastructure
{ {
[Serializable] [Serializable]
public class ValidationException : Exception public class ValidationException : DomainException
{ {
private static readonly List<ValidationError> FallbackErrors = new List<ValidationError>(); private static readonly List<ValidationError> FallbackErrors = new List<ValidationError>();
private readonly IReadOnlyList<ValidationError> errors; private readonly IReadOnlyList<ValidationError> errors;
@ -23,27 +24,29 @@ namespace Squidex.Infrastructure
get { return errors; } get { return errors; }
} }
public ValidationException(string message, params ValidationError[] errors) public string Summary { get; }
: base(message)
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) public ValidationException(string summary, IReadOnlyList<ValidationError> errors)
: base(message) : this(summary, null, errors)
{ {
this.errors = errors ?? FallbackErrors; this.errors = errors ?? FallbackErrors;
} }
public ValidationException(string message, Exception inner, params ValidationError[] errors) public ValidationException(string summary, Exception inner, params ValidationError[] errors)
: base(message, inner) : this(summary, null, errors?.ToList())
{ {
this.errors = errors != null ? errors.ToList() : FallbackErrors;
} }
public ValidationException(string message, Exception inner, IReadOnlyList<ValidationError> errors) public ValidationException(string summary, Exception inner, IReadOnlyList<ValidationError> errors)
: base(message, inner) : base(FormatMessage(summary, errors), inner)
{ {
Summary = summary;
this.errors = errors ?? FallbackErrors; 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) 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) 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