Skip to content
This repository was archived by the owner on Jan 24, 2021. It is now read-only.

Commit f1d8d49

Browse files
committed
Merge pull request #372 from grumpydev/ErrorHandlersCollection
Swithed error handler to be a collection
2 parents 555e01c + beba9a9 commit f1d8d49

File tree

7 files changed

+58
-27
lines changed

7 files changed

+58
-27
lines changed

Diff for: src/Nancy.Demo.Hosting.Aspnet/CustomErrorHandler.cs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Nancy.Demo.Hosting.Aspnet
2+
{
3+
using Nancy.ErrorHandling;
4+
5+
public class CustomErrorHandler : IErrorHandler
6+
{
7+
/// <summary>
8+
/// Whether then
9+
/// </summary>
10+
/// <param name="statusCode">Status code</param>
11+
/// <returns>True if handled, false otherwise</returns>
12+
public bool HandlesStatusCode(HttpStatusCode statusCode)
13+
{
14+
return statusCode == HttpStatusCode.ImATeapot;
15+
}
16+
17+
/// <summary>
18+
/// Handle the error code
19+
/// </summary>
20+
/// <param name="statusCode">Status code</param>
21+
/// <param name="context">Current context</param>
22+
public void Handle(HttpStatusCode statusCode, NancyContext context)
23+
{
24+
context.Response = "Response generated by a custom error handler";
25+
}
26+
}
27+
}

Diff for: src/Nancy.Demo.Hosting.Aspnet/MainModule.cs

+2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ public MainModule(IRouteCacheProvider routeCacheProvider)
129129
throw new NotSupportedException("This is an exception thrown in a route.");
130130
};
131131

132+
Get["/customErrorHandler"] = _ => HttpStatusCode.ImATeapot;
133+
132134
Get["/csrf"] = x => this.View["csrf", new { Blurb = "CSRF without an expiry using the 'session' token" }];
133135

134136
Post["/csrf"] = x =>

Diff for: src/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
<Link>Properties\SharedAssemblyInfo.cs</Link>
118118
</Compile>
119119
<Compile Include="ApplicationDependencyClass.cs" />
120+
<Compile Include="CustomErrorHandler.cs" />
120121
<Compile Include="HereBeAResponseYouScurvyDog.cs" />
121122
<Compile Include="DemoBootstrapper.cs" />
122123
<Compile Include="DependencyModule.cs" />

Diff for: src/Nancy.Testing/ConfigurableBootstrapper.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,11 @@ public ConfigurableBoostrapperConfigurator DisableAutoRegistration()
504504
/// <summary>
505505
/// Configures the bootstrapper to use the provided instance of <see cref="IErrorHandler"/>.
506506
/// </summary>
507-
/// <param name="errorHandler">The <see cref="IErrorHandler"/> instance that should be used by the bootstrapper.</param>
507+
/// <param name="errorHandlers">The <see cref="IErrorHandler"/> types that should be used by the bootstrapper.</param>
508508
/// <returns>A reference to the current <see cref="ConfigurableBoostrapperConfigurator"/>.</returns>
509-
public ConfigurableBoostrapperConfigurator ErrorHandler(IErrorHandler errorHandler)
509+
public ConfigurableBoostrapperConfigurator ErrorHandlers(params Type[] errorHandlers)
510510
{
511-
this.bootstrapper.registeredInstances.Add(
512-
new InstanceRegistration(typeof(IErrorHandler), errorHandler));
511+
this.bootstrapper.configuration.ErrorHandlers = new List<Type>(errorHandlers);
513512

514513
return this;
515514
}
@@ -521,7 +520,7 @@ public ConfigurableBoostrapperConfigurator ErrorHandler(IErrorHandler errorHandl
521520
/// <returns>A reference to the current <see cref="ConfigurableBoostrapperConfigurator"/>.</returns>
522521
public ConfigurableBoostrapperConfigurator ErrorHandler<T>() where T : IErrorHandler
523522
{
524-
this.bootstrapper.configuration.ErrorHandler = typeof(T);
523+
this.bootstrapper.configuration.ErrorHandlers = new List<Type>( new[] { typeof(T) } );
525524
return this;
526525
}
527526

Diff for: src/Nancy.Tests/Unit/NancyEngineFixture.cs

+11-11
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public NancyEngineFixture()
4040
var applicationPipelines = new Pipelines();
4141

4242
this.engine =
43-
new NancyEngine(resolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
43+
new NancyEngine(resolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
4444
{
4545
RequestPipelinesFactory = ctx => applicationPipelines
4646
};
@@ -51,7 +51,7 @@ public void Should_throw_argumentnullexception_when_created_with_null_resolver()
5151
{
5252
// Given, When
5353
var exception =
54-
Record.Exception(() => new NancyEngine(null, A.Fake<IRouteCache>(), A.Fake<INancyContextFactory>(), this.errorHandler));
54+
Record.Exception(() => new NancyEngine(null, A.Fake<IRouteCache>(), A.Fake<INancyContextFactory>(), new IErrorHandler[] { this.errorHandler }));
5555

5656
// Then
5757
exception.ShouldBeOfType<ArgumentNullException>();
@@ -62,7 +62,7 @@ public void Should_throw_argumentnullexception_when_created_with_null_routecache
6262
{
6363
// Given, When
6464
var exception =
65-
Record.Exception(() => new NancyEngine(A.Fake<IRouteResolver>(), null, A.Fake<INancyContextFactory>(), this.errorHandler));
65+
Record.Exception(() => new NancyEngine(A.Fake<IRouteResolver>(), null, A.Fake<INancyContextFactory>(), new IErrorHandler[] { this.errorHandler }));
6666

6767
// Then
6868
exception.ShouldBeOfType<ArgumentNullException>();
@@ -73,7 +73,7 @@ public void Should_throw_argumentnullexception_when_created_with_null_context_fa
7373
{
7474
// Given, When
7575
var exception =
76-
Record.Exception(() => new NancyEngine(A.Fake<IRouteResolver>(), A.Fake<IRouteCache>(), null, this.errorHandler));
76+
Record.Exception(() => new NancyEngine(A.Fake<IRouteResolver>(), A.Fake<IRouteCache>(), null, new IErrorHandler[] { this.errorHandler }));
7777

7878
// Then
7979
exception.ShouldBeOfType<ArgumentNullException>();
@@ -159,7 +159,7 @@ public void Should_not_throw_exception_when_setting_nancy_version_header_and_it_
159159
var pipelines = new Pipelines();
160160

161161
var localEngine =
162-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
162+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
163163
{
164164
RequestPipelinesFactory = ctx => pipelines
165165
};
@@ -315,7 +315,7 @@ public void HandleRequest_should_call_route_prereq_then_invoke_route_then_call_r
315315
var pipelines = new Pipelines();
316316

317317
var localEngine =
318-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
318+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
319319
{
320320
RequestPipelinesFactory = ctx => pipelines
321321
};
@@ -343,7 +343,7 @@ public void HandleRequest_should_not_invoke_route_if_route_prereq_returns_respon
343343
var pipelines = new Pipelines();
344344

345345
var localEngine =
346-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
346+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
347347
{
348348
RequestPipelinesFactory = ctx => pipelines
349349
};
@@ -366,7 +366,7 @@ public void HandleRequest_should_return_response_from_route_prereq_if_one_return
366366
var pipelines = new Pipelines();
367367

368368
var localEngine =
369-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
369+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
370370
{
371371
RequestPipelinesFactory = ctx => pipelines
372372
};
@@ -389,7 +389,7 @@ public void HandleRequest_should_allow_route_postreq_to_change_response()
389389
var pipelines = new Pipelines();
390390

391391
var localEngine =
392-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
392+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
393393
{
394394
RequestPipelinesFactory = ctx => pipelines
395395
};
@@ -411,7 +411,7 @@ public void HandleRequest_should_allow_route_postreq_to_add_items_to_context()
411411
var pipelines = new Pipelines();
412412

413413
var localEngine =
414-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
414+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
415415
{
416416
RequestPipelinesFactory = ctx => pipelines
417417
};
@@ -460,7 +460,7 @@ public void HandleRequest_route_prereq_returns_response_should_still_run_route_p
460460
pipelines.AfterRequest.AddItemToStartOfPipeline(postHook);
461461

462462
var localEngine =
463-
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, this.errorHandler)
463+
new NancyEngine(prePostResolver, A.Fake<IRouteCache>(), contextFactory, new IErrorHandler[] { this.errorHandler })
464464
{
465465
RequestPipelinesFactory = ctx => pipelines
466466
};

Diff for: src/Nancy/Bootstrapper/NancyInternalConfiguration.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static NancyInternalConfiguration Default
4747
RenderContextFactory = typeof(DefaultRenderContextFactory),
4848
ViewLocationCache = typeof(DefaultViewLocationCache),
4949
ViewLocationProvider = typeof(FileSystemViewLocationProvider),
50-
ErrorHandler = typeof(DefaultErrorHandler),
50+
ErrorHandlers = new List<Type>(new[] { typeof(DefaultErrorHandler) }.Concat(AppDomainAssemblyTypeScanner.TypesOf<IErrorHandler>(true))),
5151
CsrfTokenValidator = typeof(DefaultCsrfTokenValidator),
5252
ObjectSerializer = typeof(DefaultObjectSerializer),
5353
Serializers = new List<Type>(new[] { typeof(DefaultJsonSerializer), typeof(DefaultXmlSerializer) }),
@@ -95,7 +95,7 @@ public static NancyInternalConfiguration Default
9595

9696
public Type ViewLocationProvider { get; set; }
9797

98-
public Type ErrorHandler { get; set; }
98+
public IList<Type> ErrorHandlers { get; set; }
9999

100100
public Type CsrfTokenValidator { get; set; }
101101

@@ -163,7 +163,6 @@ public IEnumerable<TypeRegistration> GetTypeRegistations()
163163
new TypeRegistration(typeof(IRenderContextFactory), this.RenderContextFactory),
164164
new TypeRegistration(typeof(IViewLocationCache), this.ViewLocationCache),
165165
new TypeRegistration(typeof(IViewLocationProvider), this.ViewLocationProvider),
166-
new TypeRegistration(typeof(IErrorHandler), this.ErrorHandler),
167166
new TypeRegistration(typeof(ICsrfTokenValidator), this.CsrfTokenValidator),
168167
new TypeRegistration(typeof(IObjectSerializer), this.ObjectSerializer),
169168
};
@@ -178,6 +177,7 @@ public IEnumerable<CollectionTypeRegistration> GetCollectionTypeRegistrations()
178177
return new[]
179178
{
180179
new CollectionTypeRegistration(typeof(ISerializer), this.Serializers),
180+
new CollectionTypeRegistration(typeof(IErrorHandler), this.ErrorHandlers),
181181
};
182182
}
183183
}

Diff for: src/Nancy/NancyEngine.cs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
namespace Nancy
22
{
33
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
46
using System.Threading;
57
using Bootstrapper;
68
using Nancy.ErrorHandling;
@@ -16,16 +18,16 @@ public class NancyEngine : INancyEngine
1618
private readonly IRouteResolver resolver;
1719
private readonly IRouteCache routeCache;
1820
private readonly INancyContextFactory contextFactory;
19-
private readonly IErrorHandler errorHandler;
21+
private readonly IEnumerable<IErrorHandler> errorHandlers;
2022

2123
/// <summary>
2224
/// Initializes a new instance of the <see cref="NancyEngine"/> class.
2325
/// </summary>
2426
/// <param name="resolver">An <see cref="IRouteResolver"/> instance that will be used to resolve a route, from the modules, that matches the incoming <see cref="Request"/>.</param>
2527
/// <param name="routeCache">Cache of all available routes</param>
2628
/// <param name="contextFactory">A factory for creating contexts</param>
27-
/// <param name="errorHandler">Error handler</param>
28-
public NancyEngine(IRouteResolver resolver, IRouteCache routeCache, INancyContextFactory contextFactory, IErrorHandler errorHandler)
29+
/// <param name="errorHandlers">Error handlers</param>
30+
public NancyEngine(IRouteResolver resolver, IRouteCache routeCache, INancyContextFactory contextFactory, IEnumerable<IErrorHandler> errorHandlers)
2931
{
3032
if (resolver == null)
3133
{
@@ -42,15 +44,15 @@ public NancyEngine(IRouteResolver resolver, IRouteCache routeCache, INancyContex
4244
throw new ArgumentNullException("contextFactory");
4345
}
4446

45-
if (errorHandler == null)
47+
if (errorHandlers == null)
4648
{
47-
throw new ArgumentNullException("errorHandler");
49+
throw new ArgumentNullException("errorHandlers");
4850
}
4951

5052
this.resolver = resolver;
5153
this.routeCache = routeCache;
5254
this.contextFactory = contextFactory;
53-
this.errorHandler = errorHandler;
55+
this.errorHandlers = errorHandlers;
5456
}
5557

5658
/// <summary>
@@ -129,9 +131,9 @@ private void CheckErrorHandler(NancyContext context)
129131
return;
130132
}
131133

132-
if (this.errorHandler.HandlesStatusCode(context.Response.StatusCode))
134+
foreach (var errorHandler in this.errorHandlers.Where(e => e.HandlesStatusCode(context.Response.StatusCode)))
133135
{
134-
this.errorHandler.Handle(context.Response.StatusCode, context);
136+
errorHandler.Handle(context.Response.StatusCode, context);
135137
}
136138
}
137139

0 commit comments

Comments
 (0)