protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {
    if (e instanceof IOException) {
      throw (IOException) e;
    }
    // If we got here, e is not an IOException. A loaded coprocessor has a
    // fatal bug, and the server (master or regionserver) should remove the
    // faulty coprocessor from its set of active coprocessors. Setting
    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),
    // which may be useful in development and testing environments where
    // 'failing fast' for error analysis is desired.
    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {
      // server is configured to abort.
      abortServer(env, e);
    } else {
      // If available, pull a table name out of the environment
      if (env instanceof RegionCoprocessorEnvironment) {
        String tableName =
          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();
        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",
          e);
      } else {
        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);
      }

      coprocEnvironments.remove(env);
      try {
        shutdown(env);
      } catch (Exception x) {
        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);
      }
      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e
        + "' and has been removed from the active " + "coprocessor set.", e);
    }
  }
This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).
For such hooks, we should handle throwable objects depending on the Throwable's type. Those
which are instances of IOException should be passed on to the client. This is in conformance
with the HBase idiom regarding IOException: that it represents a circumstance that should be
passed along to the client for its own handling. For example, a coprocessor that implements
access controls would throw a subclass of IOException, such as AccessDeniedException, in its
preGet() method to prevent an unauthorized client's performing a Get on a particular table.
@param env Coprocessor Environment
@param e   Throwable object thrown by coprocessor.
@exception IOException Exception
hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java