Updated error handling code and readme to indicate how logging works for Ocelot

This commit is contained in:
TomPallister 2016-10-29 20:48:59 +01:00
parent 1acaaa23dd
commit 5082cc6c05
7 changed files with 58 additions and 7 deletions

View File

@ -76,4 +76,8 @@ An example startup using a yaml file for configuration can be seen below. Curren
This is pretty much all you need to get going.......more to come! This is pretty much all you need to get going.......more to come!
## Logging
Ocelot uses the standard logging interfaces ILoggerFactory / ILogger<T> as such you can use any logging provider you like such as default, nlog, serilog.

View File

@ -8,7 +8,7 @@ using Ocelot.Responses;
namespace Ocelot.Configuration.Validator namespace Ocelot.Configuration.Validator
{ {
public class ConfigurationValidator : IConfigurationValidator public class YamlConfigurationValidator : IConfigurationValidator
{ {
public Response<ConfigurationValidationResult> IsValid(YamlConfiguration configuration) public Response<ConfigurationValidationResult> IsValid(YamlConfiguration configuration)
{ {

View File

@ -35,10 +35,8 @@ namespace Ocelot.DependencyInjection
// ocelot services. // ocelot services.
services.AddSingleton<IOcelotConfigurationCreator, YamlOcelotConfigurationCreator>(); services.AddSingleton<IOcelotConfigurationCreator, YamlOcelotConfigurationCreator>();
services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>(); services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>(); services.AddSingleton<IConfigurationValidator, YamlConfigurationValidator>();
services.AddSingleton<IConfigurationValidator, ConfigurationValidator>();
return services; return services;
} }
@ -50,6 +48,8 @@ namespace Ocelot.DependencyInjection
services.AddLogging(); services.AddLogging();
// ocelot services. // ocelot services.
services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
services.AddSingleton<IAuthoriser, ClaimsAuthoriser>(); services.AddSingleton<IAuthoriser, ClaimsAuthoriser>();
services.AddSingleton<IAddClaimsToRequest, AddClaimsToRequest>(); services.AddSingleton<IAddClaimsToRequest, AddClaimsToRequest>();
services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>(); services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();

View File

@ -24,7 +24,16 @@ namespace Ocelot.Middleware
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(new EventId(1, "global error"), "Exception caught in global error handler", e); var message =
$"Exception caught in global error handler, exception message: {e.Message}, exception stack: {e.StackTrace}";
if (e.InnerException != null)
{
message = $"{message}, inner exception message {e.InnerException.Message}, inner exception stack {e.InnerException.StackTrace}";
}
_logger.LogError(new EventId(1, "Ocelot Global Error"), message, e);
context.Response.StatusCode = 500; context.Response.StatusCode = 500;
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
await context.Response.WriteAsync("Internal Server Error"); await context.Response.WriteAsync("Internal Server Error");

View File

@ -6,9 +6,33 @@
public class OcelotMiddlewareConfiguration public class OcelotMiddlewareConfiguration
{ {
/// <summary>
/// This is called after the global error handling middleware so any code before calling next.invoke
/// is the next thing called in the Ocelot pipeline. Anything after next.invoke is the last thing called
/// in the Ocelot pipeline before we go to the global error handler.
/// </summary>
public Func<HttpContext, Func<Task>, Task> PreErrorResponderMiddleware { get; set; }
/// <summary>
/// This is to allow the user to run any extra authentication before the Ocelot authentication
/// kicks in
/// </summary>
public Func<HttpContext, Func<Task>, Task> PreAuthenticationMiddleware { get; set; } public Func<HttpContext, Func<Task>, Task> PreAuthenticationMiddleware { get; set; }
/// <summary>
/// This allows the user to completely override the ocelot authentication middleware
/// </summary>
public Func<HttpContext, Func<Task>, Task> AuthenticationMiddleware { get; set; } public Func<HttpContext, Func<Task>, Task> AuthenticationMiddleware { get; set; }
/// <summary>
/// This is to allow the user to run any extra authorisation before the Ocelot authentication
/// kicks in
/// </summary>
public Func<HttpContext, Func<Task>, Task> PreAuthorisationMiddleware { get; set; } public Func<HttpContext, Func<Task>, Task> PreAuthorisationMiddleware { get; set; }
/// <summary>
/// This allows the user to completely override the ocelot authorisation middleware
/// </summary>
public Func<HttpContext, Func<Task>, Task> AuthorisationMiddleware { get; set; } public Func<HttpContext, Func<Task>, Task> AuthorisationMiddleware { get; set; }
} }
} }

View File

@ -18,17 +18,31 @@ namespace Ocelot.Middleware
public static class OcelotMiddlewareExtensions public static class OcelotMiddlewareExtensions
{ {
/// <summary>
/// Registers the Ocelot default middlewares
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder) public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder)
{ {
builder.UseOcelot(new OcelotMiddlewareConfiguration()); builder.UseOcelot(new OcelotMiddlewareConfiguration());
return builder; return builder;
} }
/// <summary>
/// Registers Ocelot with a combination of default middlewares and optional middlewares in the configuration
/// </summary>
/// <param name="builder"></param>
/// <param name="middlewareConfiguration"></param>
/// <returns></returns>
public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder, OcelotMiddlewareConfiguration middlewareConfiguration) public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder, OcelotMiddlewareConfiguration middlewareConfiguration)
{ {
// This is registered to catch any global exceptions that are not handled // This is registered to catch any global exceptions that are not handled
builder.UseExceptionHandlerMiddleware(); builder.UseExceptionHandlerMiddleware();
// Allow the user to respond with absolutely anything they want.
builder.UseIfNotNull(middlewareConfiguration.PreErrorResponderMiddleware);
// This is registered first so it can catch any errors and issue an appropriate response // This is registered first so it can catch any errors and issue an appropriate response
builder.UseHttpErrorResponderMiddleware(); builder.UseHttpErrorResponderMiddleware();

View File

@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.Configuration
public ConfigurationValidationTests() public ConfigurationValidationTests()
{ {
_configurationValidator = new ConfigurationValidator(); _configurationValidator = new YamlConfigurationValidator();
} }
[Fact] [Fact]