Skip to content

Commit

Permalink
Add flag to control exception message
Browse files Browse the repository at this point in the history
  • Loading branch information
chinadragon0515 committed Aug 3, 2016
1 parent d8c8e1a commit 3d7a54c
Show file tree
Hide file tree
Showing 18 changed files with 142 additions and 110 deletions.
23 changes: 9 additions & 14 deletions src/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Core.ServiceCollectionExtensions.#MakeTransient`1(Microsoft.Extensions.DependencyInjection.IServiceCollection)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Providers.EntityFramework.ServiceCollectionExtensions.#AddEfProviderServices`1(Microsoft.Extensions.DependencyInjection.IServiceCollection)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.ServiceCollectionExtensions.#AddODataServices`1(Microsoft.Extensions.DependencyInjection.IServiceCollection)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Routing.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,System.Func`1<Microsoft.Restier.Core.ApiBase>,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Routing.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,System.Func`1<Microsoft.Restier.Core.ApiBase>,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
#endregion

#region CA1006 Nested Generic Type
Expand All @@ -54,7 +54,6 @@
[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.Restier.Publishers.OData.Filters")]
[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.Restier.Publishers.OData.Model")]
[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.Restier.Publishers.OData.Results")]
[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.Restier.Publishers.OData.Routing")]
#endregion

#region CA1026 Default Parameter
Expand All @@ -73,8 +72,8 @@
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Core.Query.QueryResult.#.ctor(System.Collections.IEnumerable,System.Nullable`1<System.Int64>)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Security.ApiPermission.#CreateGrant(System.String,System.String,System.String,System.String,System.String)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Security.ApiPermission.#CreateDeny(System.String,System.String,System.String,System.String,System.String)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Routing.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,System.Func`1<Microsoft.Restier.Core.ApiBase>,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Routing.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,System.Func`1<Microsoft.Restier.Core.ApiBase>,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions.#MapRestierRoute`1(System.Web.Http.HttpConfiguration,System.String,System.String,Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Batch.RestierBatchHandler.#.ctor(System.Web.Http.HttpServer,System.Func`1<Microsoft.Restier.Core.ApiContext>)")]
[assembly: SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Scope = "type", Target = "Microsoft.Restier.Core.PreconditionFailedException")]
[assembly: SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Scope = "type", Target = "Microsoft.Restier.Core.ResourceNotFoundException")]
Expand Down Expand Up @@ -104,10 +103,10 @@
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Core.Submit.DataModificationItem.#ServerValues")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Providers.EntityFramework.Query.QueryExecutor.#Inner")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Query.RestierQueryExecutor.#Inner")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.ValidationResultDto.#Severity")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.ValidationResultDto.#PropertyName")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.ValidationResultDto.#Message")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.ValidationResultDto.#Id")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.ValidationResultDto.#Severity")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.ValidationResultDto.#PropertyName")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.ValidationResultDto.#Message")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.ValidationResultDto.#Id")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Model.ModelMapper.#InnerMapper")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Model.RestierModelBuilder.#InnerModelBuilder")]
[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Model.RestierModelExtender+ModelBuilder.#.ctor(Microsoft.Restier.Publishers.OData.Model.RestierModelExtender)")]
Expand Down Expand Up @@ -186,11 +185,7 @@

#region CA2000 Dispose objects
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.RestierController.#CreateQueryResponse(System.Linq.IQueryable,Microsoft.OData.Edm.IEdmType,System.Boolean,System.Web.OData.Formatter.ETag)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.RestierExceptionFilterAttribute.#Handler403(System.Web.Http.Filters.HttpActionExecutedContext,System.Threading.CancellationToken)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.RestierExceptionFilterAttribute.#Handler404(System.Web.Http.Filters.HttpActionExecutedContext,System.Threading.CancellationToken)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.RestierExceptionFilterAttribute.#Handler412(System.Web.Http.Filters.HttpActionExecutedContext,System.Threading.CancellationToken)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.RestierExceptionFilterAttribute.#Handler428(System.Web.Http.Filters.HttpActionExecutedContext,System.Threading.CancellationToken)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.Filters.RestierExceptionFilterAttribute.#Handler501(System.Web.Http.Filters.HttpActionExecutedContext,System.Threading.CancellationToken)")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Restier.Publishers.OData.RestierExceptionFilterAttribute.#HandleCommonException(System.Web.Http.Filters.HttpActionExecutedContext,System.Boolean,System.Threading.CancellationToken)")]
#endregion

#region CA1812 Uninstantiated internal classes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
#if !EF7
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
using Microsoft.Restier.Core.Submit;
using Net::System.Net.Http.Formatting;

namespace Microsoft.Restier.Publishers.OData.Filters
namespace Microsoft.Restier.Publishers.OData
{
/// <summary>
/// An ExceptionFilter that is capable of serializing well-known exceptions to the client.
Expand All @@ -29,16 +29,13 @@ internal sealed class RestierExceptionFilterAttribute : ExceptionFilterAttribute
{
private static readonly List<ExceptionHandlerDelegate> Handlers = new List<ExceptionHandlerDelegate>
{
Handler400,
Handler403,
Handler404,
Handler412,
Handler428,
Handler501
HandleChangeSetValidationException,
HandleCommonException
};

private delegate Task<HttpResponseMessage> ExceptionHandlerDelegate(
HttpActionExecutedContext context,
bool useVerboseErros,
CancellationToken cancellationToken);

/// <summary>
Expand All @@ -51,9 +48,12 @@ public override async Task OnExceptionAsync(
HttpActionExecutedContext actionExecutedContext,
CancellationToken cancellationToken)
{
var config = actionExecutedContext.Request.GetConfiguration();
var useVerboseErros = config.GetUseVerboseErrors();

foreach (var handler in Handlers)
{
var result = await handler.Invoke(actionExecutedContext, cancellationToken);
var result = await handler.Invoke(actionExecutedContext, useVerboseErros, cancellationToken);

if (result != null)
{
Expand All @@ -63,8 +63,9 @@ public override async Task OnExceptionAsync(
}
}

private static async Task<HttpResponseMessage> Handler400(
private static async Task<HttpResponseMessage> HandleChangeSetValidationException(
HttpActionExecutedContext context,
bool useVerboseErros,
CancellationToken cancellationToken)
{
ChangeSetValidationException validationException = context.Exception as ChangeSetValidationException;
Expand All @@ -79,84 +80,60 @@ private static async Task<HttpResponseMessage> Handler400(
return await exceptionResult.ExecuteAsync(cancellationToken);
}

var odataException = context.Exception as ODataException;
if (odataException != null)
{
return context.Request.CreateErrorResponse(HttpStatusCode.BadRequest, context.Exception);
}

return null;
}

private static Task<HttpResponseMessage> Handler403(
private static Task<HttpResponseMessage> HandleCommonException(
HttpActionExecutedContext context,
bool useVerboseErros,
CancellationToken cancellationToken)
{
if (context.Exception is SecurityException)
var exception = context.Exception;
if (exception is AggregateException)
{
return Task.FromResult(
context.Request.CreateErrorResponse(HttpStatusCode.Forbidden, context.Exception));
// In async call, the exception will be wrapped as AggregateException
exception = exception.InnerException;
}

return Task.FromResult<HttpResponseMessage>(null);
}

private static Task<HttpResponseMessage> Handler404(
HttpActionExecutedContext context,
CancellationToken cancellationToken)
{
var notFoundException = context.Exception as ResourceNotFoundException;
if (notFoundException != null)
if (exception == null)
{
return Task.FromResult(
context.Request.CreateErrorResponse(HttpStatusCode.NotFound, context.Exception));
return Task.FromResult<HttpResponseMessage>(null);
}

return Task.FromResult<HttpResponseMessage>(null);
}

private static Task<HttpResponseMessage> Handler412(
HttpActionExecutedContext context,
CancellationToken cancellationToken)
{
if (context.Exception is PreconditionFailedException)
HttpStatusCode code = HttpStatusCode.Unused;
if (exception is ODataException)
{
return Task.FromResult(
context.Request.CreateErrorResponse(HttpStatusCode.PreconditionFailed, context.Exception));
code = HttpStatusCode.BadRequest;
}

return Task.FromResult<HttpResponseMessage>(null);
}

private static Task<HttpResponseMessage> Handler428(
HttpActionExecutedContext context,
CancellationToken cancellationToken)
{
if (context.Exception is PreconditionRequiredException)
else if (exception is SecurityException)
{
return Task.FromResult(
context.Request.CreateErrorResponse((HttpStatusCode)428, context.Exception));
code = HttpStatusCode.Forbidden;
}

return Task.FromResult<HttpResponseMessage>(null);
}

private static Task<HttpResponseMessage> Handler501(
HttpActionExecutedContext context,
CancellationToken cancellationToken)
{
if (context.Exception is NotImplementedException)
else if (exception is ResourceNotFoundException)
{
return Task.FromResult(
context.Request.CreateErrorResponse(HttpStatusCode.NotImplemented, context.Exception));
code = HttpStatusCode.NotFound;
}
else if (exception is PreconditionFailedException)
{
code = HttpStatusCode.PreconditionFailed;
}
else if (exception is PreconditionRequiredException)
{
code = (HttpStatusCode)428;
}
else if (context.Exception is NotImplementedException)
{
code = HttpStatusCode.NotImplemented;
}

// For async call, the exception is wrapped.
if (context.Exception is AggregateException
&& context.Exception.InnerException is NotImplementedException)
if (code != HttpStatusCode.Unused)
{
return Task.FromResult(
context.Request.CreateErrorResponse(HttpStatusCode.NotImplemented, context.Exception));
if (useVerboseErros)
{
return Task.FromResult(context.Request.CreateErrorResponse(code, exception));
}

return Task.FromResult(context.Request.CreateErrorResponse(code, exception.Message));
}

return Task.FromResult<HttpResponseMessage>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Diagnostics.Tracing;
using Microsoft.Restier.Core.Submit;

namespace Microsoft.Restier.Publishers.OData.Filters
namespace Microsoft.Restier.Publishers.OData
{
/// <summary>
/// A data transfer object that is used to serialize ValidationResult instances to the client.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArguementsCannotbeNull" xml:space="preserve">
<value>The argument with name {0} cannot be null.</value>
</data>
<data name="BatchHandlerRequiresApiContextFactory" xml:space="preserve">
<value>RestierBatchHandler was called without an ApiContext Factory.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
using Microsoft.Restier.Core.Query;
using Microsoft.Restier.Core.Submit;
using Microsoft.Restier.Publishers.OData.Batch;
using Microsoft.Restier.Publishers.OData.Filters;
using Microsoft.Restier.Publishers.OData.Formatter;
using Microsoft.Restier.Publishers.OData.Properties;
using Microsoft.Restier.Publishers.OData.Query;
Expand Down
Loading

0 comments on commit 3d7a54c

Please sign in to comment.