WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

Endpoint
Name:Exception Handler
Description:Catches exceptions and delegates handling to a declaratively specified handler service.
Id:layer1.ExceptionHandler
Category:transparent overlay

Exception Handler is a transparent overlay. You must instantiate an instance of the overlay from its prototype, this will create a new instance within your application space.

Parameters

The layer1.ExceptionHandler prototype has the following initialisation parameters:

NameRulesTypingDefaultDescription
spaceMandatorySpace(none)
A nested space definition which the overlay will delegate all requests in to.

Here is an auto-generated example of how to instantiate an instance of Exception Handler:

<overlay>
  <prototype>layer1.ExceptionHandler</prototype>
  <space>
    <!--wrapped space...-->
  </space>
</overlay>
Import Requirements

To use Exception Handler transparent overlay you must import the module urn:org:netkernel:ext:layer1:

<import>
  <uri>urn:org:netkernel:ext:layer1</uri>
</import>

The ExceptionHandler will catch all unhandled exceptions which are thrown from the handling of requests which pass through it. If no exception occurs then the ExceptionHandler is completely transparent. When an exception is thrown it's id field is looked up in the configuration to determine how to handle the exception.

The exception handler reads a configuration resource from the fixed location of res:/etc/ExceptionHandlerConfig.xml. The configuration must be a well formed XML document with a root tag of <config> containing one or more <exceptionHandler> tags which define specific handler services for specific exception ids.

Here is an example from PhotoNK:

<config>
  <exceptionHandler>
    <id>SecurityException</id>
    <target>photonk:securityExceptionHandler</target>
  </exceptionHandler>
  <exceptionHandler>
    <id>default</id>
    <target>photonk:defaultExceptionHandler</target>
  </exceptionHandler>
</config>

The <id> tag specifies the id field from the deepest cause of the caught exception, this equivalent to the NKFException.getDeepestId(). The value of "default" is a reserved value to indicate that this handler should be used when all other specific matches for id fail.

The <target> tag specifies the logical endpoint id of the handler endpoint to SOURCE when a match is found. The handler endpoint has very specific interface requirements, it must have three arguments:

  • failedRequest - which receives an INKFRequestReadOnly which is the request which the exception was thrown within.
  • exception - the exception that was thrown wrapped inside an org.netkernel.layer0.representation.WrappedThrowable representation.
  • handler - the <exceptionHandler> node as an org.netkernel.layer0.representation.IHDSNode.

The response from the exception handler overlay is passed through transparently if no exception is thrown or if an exception is thrown but no handler is found that matches the thrown exception. Otherwise the response from the exception handler is whatever response is returned from the exception handler.

Here is an example endpoint declaration for the defaultExceptionHandler in the example above:

<endpoint>
  <id>photonk:defaultExceptionHandler</id>
  <grammar>
    <active>
      <identifier>active:defaultExceptionHandler</identifier>
      <varargs />
    </active>
  </grammar>
  <class>photonk.DefaultExceptionHandlerEndpoint</class>
</endpoint>

and an example Handler:

public class DefaultExceptionHandler extends StandardAccessorImpl
{
    public void onSource(INKFRequestContext aContext) throws Exception
    {   
        NKFException ex=(NKFException)aContext.source("arg:exception",WrappedThrowable.class).getThrowable();
        INKFRequestReadOnly req = aContext.source("arg:failedRequest",INKFRequestReadOnly.class);
        IHDSNode handlerNode = aContext.source("arg:handler",IHDSNode.class);
        aContext.createResponseFrom("Handled!");
    }
}