void sendFailure(UserRpcException e) { sendOnce(); UserException uex = UserException.systemError(e).addIdentity(e.getEndpoint()).build(logger); logger.error("Unexpected Error while handling request message", e); OutboundRpcMessage outMessage = new OutboundRpcMessage( RpcMode.RESPONSE_FAILURE, 0, coordinationId, uex.getOrCreatePBError(false)); if (RpcConstants.EXTRA_DEBUGGING) { logger.debug("Adding message to outbound buffer. {}", outMessage); } connection.getChannel().writeAndFlush(outMessage); }
@Override public void close() { Preconditions.checkState(!isClosed); Preconditions.checkState(resultState != null); logger.info("foreman cleaning up."); injector.injectPause(queryContext.getExecutionControls(), "foreman-cleanup", logger); // remove the channel disconnected listener (doesn't throw) closeFuture.removeListener(closeListener); // log the query summary logQuerySummary(); // These are straight forward removals from maps, so they won't throw. drillbitContext.getWorkBus().removeFragmentStatusListener(queryId); drillbitContext .getClusterCoordinator() .removeDrillbitStatusListener(queryManager.getDrillbitStatusListener()); suppressingClose(queryContext); /* * We do our best to write the latest state, but even that could fail. If it does, we can't write * the (possibly newly failing) state, so we continue on anyway. * * We only need to do this if the resultState differs from the last recorded state */ if (resultState != state) { suppressingClose( new AutoCloseable() { @Override public void close() throws Exception { recordNewState(resultState); } }); } /* * Construct the response based on the latest resultState. The builder shouldn't fail. */ final QueryResult.Builder resultBuilder = QueryResult.newBuilder().setQueryId(queryId).setQueryState(resultState); final UserException uex; if (resultException != null) { final boolean verbose = queryContext.getOptions().getOption(ExecConstants.ENABLE_VERBOSE_ERRORS_KEY).bool_val; uex = UserException.systemError(resultException) .addIdentity(queryContext.getCurrentEndpoint()) .build(logger); resultBuilder.addError(uex.getOrCreatePBError(verbose)); } else { uex = null; } // we store the final result here so we can capture any error/errorId in the profile for later // debugging. queryManager.writeFinalProfile(uex); /* * If sending the result fails, we don't really have any way to modify the result we tried to send; * it is possible it got sent but the result came from a later part of the code path. It is also * possible the connection has gone away, so this is irrelevant because there's nowhere to * send anything to. */ try { // send whatever result we ended up with initiatingClient.sendResult(responseListener, resultBuilder.build(), true); } catch (final Exception e) { addException(e); logger.warn("Exception sending result to client", resultException); } // Remove the Foreman from the running query list. bee.retireForeman(Foreman.this); try { releaseLease(); } finally { isClosed = true; } }
private static void throwAsUnsupportedException(UserException ex) throws Exception { SqlUnsupportedException.errorClassNameToException( ex.getOrCreatePBError(false).getException().getExceptionClass()); throw ex; }