Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added tests and fix for view location error. #769

Merged
merged 1 commit into from

2 participants

Steven Robbins Andreas Håkansson
Steven Robbins
Owner

Processors are now no longer wrapped in a safe execution method
so exceptions are bubbled up. Returning null from a propcessor
will execute the next one, so if anything goes wrong when processing
in your processor.. catch it, log it, return null :-)

Steven Robbins grumpydev Added tests and fix for view location error.
Processors are now no longer wrapped in a safe execution method
so exceptions are bubbled up. Returning null from a propcessor
will execute the next one, so if anything goes wrong when processing
in your processor.. catch it, log it, return null :-)
a9c21b4
Steven Robbins grumpydev was assigned
Andreas Håkansson thecodejunkie merged commit e5f8dc1 into from
Steven Robbins grumpydev deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 1, 2012
  1. Steven Robbins

    Added tests and fix for view location error.

    grumpydev authored
    Processors are now no longer wrapped in a safe execution method
    so exceptions are bubbled up. Returning null from a propcessor
    will execute the next one, so if anything goes wrong when processing
    in your processor.. catch it, log it, return null :-)
This page is out of date. Refresh to see the latest.
123 src/Nancy.Tests.Functional/Tests/ContentNegotiationFixture.cs
View
@@ -4,6 +4,7 @@ namespace Nancy.Tests.Functional.Tests
using System.Collections.Generic;
using System.IO;
+ using Nancy.ErrorHandling;
using Nancy.IO;
using Nancy.Responses.Negotiation;
using Nancy.Testing;
@@ -372,22 +373,6 @@ public void Should_add_link_header_for_matching_response_processors()
Assert.True(response.Headers["Link"].Contains(@"</.xml>; rel=""application/xml"""));
}
- private static Func<dynamic, dynamic> CreateNegotiatedResponse(Action<Negotiator> action = null)
- {
- var context =
- new NancyContext { NegotiationContext = new NegotiationContext() };
-
- var negotiator =
- new Negotiator(context);
-
- if (action != null)
- {
- action.Invoke(negotiator);
- }
-
- return parameters => negotiator;
- }
-
[Fact]
public void Should_set_negotiated_status_code_to_response_when_set_as_integer()
{
@@ -442,6 +427,77 @@ public void Should_set_negotiated_status_code_to_response_when_set_as_httpstatus
Assert.Equal(HttpStatusCode.InsufficientStorage, response.StatusCode);
}
+ [Fact]
+ public void Should_throw_exception_if_view_location_fails()
+ {
+ var browser = new Browser(with =>
+ {
+ with.ResponseProcessor<ViewProcessor>();
+
+ with.Module(new FakeModuleInvalidViewName());
+ });
+
+ // When
+ var result = Record.Exception(() =>
+ {
+ var response = browser.Get(
+ "/FakeModuleInvalidViewName",
+ with =>
+ { with.Accept("text/html", 1.0m); });
+ });
+
+ // Then
+ Assert.NotNull(result);
+ Assert.Contains("Unable to locate view", result.ToString());
+ }
+
+ [Fact]
+ public void Should_use_next_processor_if_processor_returns_null()
+ {
+ // Given
+ var browser = new Browser(with =>
+ {
+ with.ResponseProcessors(typeof(NullProcessor), typeof(TestProcessor));
+
+ with.Module(new ConfigurableNancyModule(x =>
+ {
+ x.Get("/test", CreateNegotiatedResponse(config =>
+ {
+ config.WithAllowedMediaRange("application/xml");
+ }));
+ }));
+ });
+
+ // When
+ var response = browser.Get("/test", with =>
+ {
+ with.Accept("application/xml", 0.9m);
+ });
+
+ // Then
+ var bodyResult = response.Body.AsString();
+ Assert.True(bodyResult.StartsWith("application/xml"), string.Format("Body should have started with 'application/xml' but was actually '{0}'", bodyResult));
+ }
+
+ private static Func<dynamic, dynamic> CreateNegotiatedResponse(Action<Negotiator> action = null)
+ {
+ var context =
+ new NancyContext { NegotiationContext = new NegotiationContext() };
+
+ var negotiator =
+ new Negotiator(context);
+
+ if (action != null)
+ {
+ action.Invoke(negotiator);
+ }
+
+ return parameters =>
+ {
+ return negotiator;
+ };
+ }
+
/// <summary>
/// Test response processor that will accept any type
/// and put the content type and model type into the
@@ -475,6 +531,33 @@ public Response Process(MediaRange requestedMediaRange, dynamic model, NancyCont
}
}
+ public class NullProcessor : IResponseProcessor
+ {
+ private const string ResponseTemplate = "{0}\n{1}";
+
+ public IEnumerable<Tuple<string, MediaRange>> ExtensionMappings
+ {
+ get
+ {
+ yield break;
+ }
+ }
+
+ public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
+ {
+ return new ProcessorMatch
+ {
+ RequestedContentTypeResult = MatchResult.ExactMatch,
+ ModelResult = MatchResult.ExactMatch
+ };
+ }
+
+ public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
+ {
+ return null;
+ }
+ }
+
public class ModelProcessor : IResponseProcessor
{
private const string ResponseTemplate = "{0}\n{1}";
@@ -501,5 +584,13 @@ public Response Process(MediaRange requestedMediaRange, dynamic model, NancyCont
return (string) model;
}
}
+
+ public class FakeModuleInvalidViewName : NancyModule
+ {
+ public FakeModuleInvalidViewName()
+ {
+ Get["/FakeModuleInvalidViewName"] = _ => View["blahblahblah"];
+ }
+ }
}
}
16 src/Nancy/Routing/DefaultRouteInvoker.cs
View
@@ -100,7 +100,7 @@ private static Response NegotiateResponse(IEnumerable<Tuple<string, IEnumerable<
context.WriteTraceLog(sb => sb.AppendFormat("[DefaultRouteInvoker] Invoking processor: {0}\n", processorType));
var response =
- SafeInvokeResponseProcessor(prioritizedProcessor.Item1, compatibleHeader.Item1, negotiator.NegotiationContext.GetModelForMediaRange(compatibleHeader.Item1), context);
+ prioritizedProcessor.Item1.Process(compatibleHeader.Item1, negotiator.NegotiationContext.GetModelForMediaRange(compatibleHeader.Item1), context);
if (response != null)
{
@@ -247,20 +247,6 @@ private static void AddLinkHeaders(NancyContext context, IEnumerable<Tuple<strin
return currentHeaders;
}
- private static Response SafeInvokeResponseProcessor(IResponseProcessor responseProcessor, MediaRange mediaRange, object model, NancyContext context)
- {
- try
- {
- return responseProcessor.Process(mediaRange, model, context);
- }
- catch (Exception e)
- {
- context.WriteTraceLog(sb => sb.AppendFormat("[DefaultRouteInvoker] Processor threw {0} exception: {1}", e.GetType(), e.Message));
- }
-
- return null;
- }
-
private static Negotiator GetNegotiator(object routeResult, NancyContext context)
{
var negotiator = routeResult as Negotiator;
Something went wrong with that request. Please try again.