@Override
  public void close() throws IOException {
    try {
      iter.close();
    } catch (RuntimeException e) {
      throw new IOException(e.getMessage(), e);
    }
  }
@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
    }
  }