static boolean isSystemHealthError(Exception exception) {
    boolean isSystemHealthError = true;
    boolean isInternalError = false;
    if (exception instanceof RouterException) {
      RouterErrorCode routerErrorCode = ((RouterException) exception).getErrorCode();
      switch (routerErrorCode) {
        // The following are user errors. Only increment the respective error metric.
        case InvalidBlobId:
        case InvalidPutArgument:
        case BlobTooLarge:
        case BadInputChannel:
        case BlobDeleted:
        case BlobExpired:
        case BlobAuthorizationFailure:
        case BlobDoesNotExist:
        case RangeNotSatisfiable:
        case ChannelClosed:
        case BlobUpdateNotAllowed:
          isSystemHealthError = false;
          break;
        case BlobCorrupted:
        case UnexpectedInternalError:
          isInternalError = true;
          break;
      }
    } else if (Utils.isPossibleClientTermination(exception)) {
      isSystemHealthError = false;
    }
    if (isSystemHealthError) {
      if (isInternalError) {
        logger.error("Router operation met with a system health error: ", exception);
      } else {
        // Be less verbose with transient errors like operation timeouts
        logger.warn("Router operation error: {}", exception.toString());
      }
    }
    return isSystemHealthError;
  }
Determine if an error is indicative of the health of the system, and not a user error.
If it is a system health error, then the error is logged.
@param exception The {@link Exception} to check.
@return true if this is an internal error and not a user error; false otherwise.
ambry-router/src/main/java/com/github/ambry/router/RouterUtils.java