Error Handling

Templates uses Exceptions for error flow control flow that by default will fail fast by emitting the Exception details at
the point where the error occured before terminating the Stream and rethrowing the Exception which lets you for
instance catch the Exception in Unit Tests.

Handled Exceptions

You can instead choose to handle exceptions and prevent them from short-circuiting page rendering by assigning them to an
argument using either the assignError filter which will capture any subsequent Exceptions thrown on the page:

Alternatively it can be specified on each call-site where it will capture the Exception thrown by the filter:

Unhandled Exceptions Behavior

If Exceptions are unassigned they're considered to be unhandled. The default behavior for TemplateContext is to
rethrow Exceptions, but as ServiceStack's TemplatePagesFeature is executed within the context of a HTTP Server
it's default is configured to:

newTemplateContext {
SkipExecutingFiltersIfError = true
}

Which instead captures any unhandled Exceptions in PageResult.LastFilterError and continues rendering the page except
it skips evaluating any subsequent filters and instead only evaluates the filters which handle errors,
currently:

This behavior provides the optimal UX for developers and end-users as HTML Pages with Exceptions are still rendered well-formed
whilst still being easily able to display a curated error messages for end-users without developers needing to guard against
executing filters when Exceptions occur.

Controlling Unhandled Exception Behavior

We can also enable this behavior on a per-page basis using the skipExecutingFiltersOnError filter:

Here we can see that any normal filters after exceptions are never evaluated unless they're specifically for handling Errors.

Continue Executing Filters on Unhandled Exceptions

We can also specify that we want to continue executing filters in which case you'll need to manually guard filters you want to
control the execution of using the ifNoError or ifError filters:

Accessing Page Exceptions

The last Exception thrown are accessible using the lastError* filters:

Throwing Exceptions

We've included a few of the popular Exception Types, filters prefixed with throw always throws the Exceptions below:

Ensure Argument Helpers

The ensureAll* filters assert the state of multiple arguments where it will either throw an Exception unless
all the arguments meet the condition or return the Object Dictionary if all conditions are met:

The ensureAny* filters only requires one of the arguments meet the condition to return the Object Dictionary:

Fatal Exceptions

The Exception Types below are reserved for Exceptions that should never happen, such as incorrect usage of an API where it would've
resulted in a compile error in C#. When these Exceptions are thrown in a filter or a page they'll immediately short-circuit execution of
the page and write the Exception details to the output.
The Fatal Exceptions include:

NotSupportedException

NotImplementedException

TargetInvocationException

Rendering Exceptions

The OnExpressionException delegate in
Page Formats
are able to control how Exceptions in filter expressions are rendered where if preferred exceptions can be rendered in-line
in the filter expression where they occured with:

The OnExpressionException can also suppress Exceptions from being displayed by capturing any naked Exception Types registered in
TemplateConfig.CaptureAndEvaluateExceptionsToNull
and evaluate the filter expression to null which by default will suppress the following naked Exceptions thrown in filters:

NullReferenceException

ArgumentNullException

Implementing Filter Exceptions

In order for your own Filter Exceptions to participate in the above Template Error Handling they'll need to be wrapped in an
StopFilterExecutionException including both the Template's scope and an optional options object
which is used to check if the assignError binding was provided so it can automatically populate it with the Exception.

The easiest way to Implement Exception handling in filters is to call a managed function which catches all Exceptions and
throws them in a StopFilterExecutionException as seen in OrmLite's
TemplateDbFilters: