### Question:
ExceptionHandler { @SuppressWarnings("unchecked") public <I> boolean execute(C context, I input, Procedure<I> procedure) throws ProcessException, DiscontinuedException { return execute(context, input, procedure, (OnError<C, I>) onError); }  void mapException(Function<Exception, ErrorTypes> mapException); void adjustError(BiFunction<C, ErrorTypes, Result> adjustError); void onError(OnError<C, ?> onError); @SuppressWarnings("unchecked") boolean execute(C context, I input, Procedure<I> procedure); boolean execute(C context, I input, Procedure<I> procedure, OnError<C, I> onError); static ExceptionHandler.OnError<C, FlowFile> createOnError(
            final ProcessContext context, final ProcessSession session, final RoutingResult routingResult,
            final Relationship relFailure, final Relationship relRetry); static ExceptionHandler.OnError<C, I> createOnGroupError(
            final ProcessContext context, final ProcessSession session, final RoutingResult routingResult,
            final Relationship relFailure, final Relationship relRetry);  }### Answer:
@Test public void testBasicUsage() { final ExternalProcedure p = new ExternalProcedure(); try { final int r1 = p.divide(4, 2); assertEquals(2, r1); } catch (Exception e) { e.printStackTrace(); } final Context context = new Context(); final ExceptionHandler<Context> handler = new ExceptionHandler<>(); handler.execute(context, 6, i -> { final int r2 = p.divide(i, 2); assertEquals(3, r2); }); AtomicReference<Integer> r = new AtomicReference<>(); handler.execute(context, 8, i -> r.set(p.divide(i, 2))); assertEquals(4, r.get().intValue()); try { final Integer nullInput = null; handler.execute(context, nullInput, i -> r.set(p.divide(i, 2))); fail("Exception should be thrown because input is null."); } catch (ProcessException e) { assertTrue(e.getCause() instanceof NullPointerException); } }