private void onError(int statusCode) throws Exception {
		// if status code is [200 300) range response body is accessible via getInputStream
		// otherwise getErrorStream should be used
		// trying to use getInputStream for status codes not in [200 300) range will rise IOException

		switch (statusCode) {
		case SC_FORBIDDEN:
			// server understood the request but refuses to fulfill it
			// compared with SC_UNAUTHORIZED, sending authentication will not grant access
			// common SC_FORBIDDEN condition may be Tomcat filtering by remote address and client IP is not allowed
			throw new RmiException("Server refuses to process request |%s|. Common cause may be Tomcat filtering by remote address and this IP is not allowed.", connection.getURL());

		case SC_UNAUTHORIZED:
			throw new RmiException("Attempt to access private remote method |%s| without authorization.", connection.getURL());

		case SC_NOT_FOUND:
			// not found may occur if front end Apache HTTP server does not recognize the protocol, e.g. trying to access
			// securely a
			// public method or because of misspelled extension; also virtual host configuration for remote context may be wrong
			throw new RmiException("Method |%s| not found. Check URL spelling, protocol unmatched or unrecognized extension.", connection.getURL());

		case SC_SERVICE_UNAVAILABLE:
			// front end HTTP server is running but application server is down; front end server responds with 503
			throw new RmiException("Front-end HTTP server is up but back-end is down. HTTP-RMI transaction |%s| aborted.", connection.getURL());

		case SC_BAD_REQUEST:
			if (isJSON(connection.getContentType())) {
				// business constrain not satisfied
				throw (BusinessException) readJsonObject(connection.getErrorStream(), BusinessException.class);
			}
			break;

		case SC_INTERNAL_SERVER_ERROR:
			if (isJSON(connection.getContentType())) {
				RemoteException remoteException = (RemoteException) readJsonObject(connection.getErrorStream(), RemoteException.class);
				log.error("HTTP-RMI error on |%s|: %s", connection.getURL(), remoteException);

				// if remote exception is an exception declared by method signature we throw it in this virtual machine
				if (exceptions.contains(getRemoteExceptionCause(remoteException))) {
					Class<? extends Throwable> cause = Classes.forOptionalName(remoteException.getCause());
					if (cause != null) {
						String message = remoteException.getMessage();
						if (message == null) {
							throw (Exception) Classes.newInstance(cause);
						}
						throw (Exception) Classes.newInstance(cause, remoteException.getMessage());
					}
				}

				// if received remote exception is not listed by method signature replace it with RmiException
				throw new RmiException(connection.getURL(), remoteException);
			}
		}

		final InputStream errorStream = connection.getErrorStream();
		if (errorStream != null) {
			String responseDump = Strings.load(errorStream, 100);
			log.error("HTTP-RMI error on |%s|. Server returned |%d|. Response dump:\r\n\t%s", connection.getURL(), statusCode, responseDump);
		} else {
			log.error("HTTP-RMI error on |%s|. Server returned |%d|.", connection.getURL(), statusCode);
		}
		throw new RmiException("HTTP-RMI error on |%s|. Server returned |%d|.", connection.getURL(), statusCode);
	}
private void onError ( int statusCode ) throws Exception { switch ( statusCode ) { case SC_FORBIDDEN : throw new RmiException ( "Server refuses to process request |%s|. Common cause may be Tomcat filtering by remote address and this IP is not allowed." , connection . getURL ( ) ) ; case SC_UNAUTHORIZED : throw new RmiException ( "Attempt to access private remote method |%s| without authorization." , connection . getURL ( ) ) ; case SC_NOT_FOUND : throw new RmiException ( "Method |%s| not found. Check URL spelling, protocol unmatched or unrecognized extension." , connection . getURL ( ) ) ; case SC_SERVICE_UNAVAILABLE : throw new RmiException ( "Front-end HTTP server is up but back-end is down. HTTP-RMI transaction |%s| aborted." , connection . getURL ( ) ) ; case SC_BAD_REQUEST : if ( isJSON ( connection . getContentType ( ) ) ) { throw ( BusinessException ) readJsonObject ( connection . getErrorStream ( ) , BusinessException . class ) ; } break ; case SC_INTERNAL_SERVER_ERROR : if ( isJSON ( connection . getContentType ( ) ) ) { RemoteException remoteException = ( RemoteException ) readJsonObject ( connection . getErrorStream ( ) , RemoteException . class ) ; log . error ( "HTTP-RMI error on |%s|: %s" , connection . getURL ( ) , remoteException ) ; if ( exceptions . contains ( getRemoteExceptionCause ( remoteException ) ) ) { Class < ? extends Throwable > cause = Classes . forOptionalName ( remoteException . getCause ( ) ) ; if ( cause != null ) { String message = remoteException . getMessage ( ) ; if ( message == null ) { throw ( Exception ) Classes . newInstance ( cause ) ; } throw ( Exception ) Classes . newInstance ( cause , remoteException . getMessage ( ) ) ; } } throw new RmiException ( connection . getURL ( ) , remoteException ) ; } } final InputStream errorStream = connection . getErrorStream ( ) ; if ( errorStream != null ) { String responseDump = Strings . load ( errorStream , 100 ) ; log . error ( "HTTP-RMI error on |%s|. Server returned |%d|. Response dump:\r\n\t%s" , connection . getURL ( ) , statusCode , responseDump ) ; } else { log . error ( "HTTP-RMI error on |%s|. Server returned |%d|." , connection . getURL ( ) , statusCode ) ; } throw new RmiException ( "HTTP-RMI error on |%s|. Server returned |%d|." , connection . getURL ( ) , statusCode ) ; }
Handle transaction error.

@param statusCode HTTP response status code.
@throws IOException if reading connection error stream fails.
@throws RmiException for all error codes less business exception and internal server error.
@throws BusinessException if server side logic detects that a business constrain is broken.
@throws Exception internal server error is due to a checked exception present into remote method signature.