@Test
public void testExceptionHandling() throws Exception {

  InvocationHandler rtExcHandler = new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
      throw new RuntimeException("forced runtime error");
    }
  };
  DBIterator dbiter = (DBIterator) Proxy.newProxyInstance(
      DBIterator.class.getClassLoader(), new Class[] { DBIterator.class },
      rtExcHandler);
  LeveldbIterator iter = new LeveldbIterator(dbiter);
  for (CallInfo ci : RTEXC_METHODS) {
    Method method = iter.getClass().getMethod(ci.methodName, ci.argTypes);
    assertNotNull("unable to locate method " + ci.methodName, method);
    try {
      method.invoke(iter, ci.args);
      fail("operation should have thrown");
    } catch (InvocationTargetException ite) {
      Throwable exc = ite.getTargetException();
      assertTrue("Method " + ci.methodName + " threw non-DBException: "
          + exc, exc instanceof DBException);
      assertFalse("Method " + ci.methodName + " double-wrapped DBException",
          exc.getCause() instanceof DBException);
    }
  }
  // check close() throws IOException
  try {
    iter.close();
    fail("operation shoul have thrown");
  } catch (IOException e) {
    // expected
  }
}