def failureToResult()

in backend/app/utils/controller/FailureToResultMapper.scala [25:139]


  def failureToResult(err: Failure, user: Option[User] = None): Result = {

    def logUserAndMessage(user: Option[User], errorString: String) =
      user match {
        case Some(user) => logger.error(user.asLogMarker, errorString)
        case None => logger.error(errorString)
      }

    err match {
      case hidden : HiddenFailure =>
        // don't leak the reason that the sensitive failure occurred - log it locally and return an ambiguous error
        logger.error(s"${hidden.msg}: ${hidden.actualMessage}", hidden.cause.orNull)
        Results.Unauthorized(hidden.msg)
      case MisconfiguredAccount(msg) =>
        logUserAndMessage(user, s"Misconfigured account: $msg")
        Results.Forbidden(msg)
      case SecondFactorRequired(msg) =>
        logUserAndMessage(user, s"Unauthorised, second factor auth required: $msg")
        Results.Unauthorized(msg).withHeaders(HeaderNames.WWW_AUTHENTICATE -> "Pfi2fa")
      case PanDomainCookieInvalid(msg, _) =>
        logUserAndMessage(user, s"Pan domain login failure: $msg")
        Results.Unauthorized(msg).withHeaders(HeaderNames.WWW_AUTHENTICATE -> "Panda")
      case ClientFailure(msg) =>
        logUserAndMessage(user, s"Bad request: $msg")
        Results.BadRequest(msg)
      case NotFoundFailure(msg) =>
        logUserAndMessage(user, s"Not found: $msg")
        Results.NotFound(msg)
      case UnsupportedOperationFailure(msg) =>
        logUserAndMessage(user, s"Unsupported Operation: $msg")
        Results.BadRequest(msg)
      case JsonParseFailure(errors) =>
        logUserAndMessage(user, s"Json parse failure: $errors")
        Results.BadRequest(JsError.toJson(errors))
      case IllegalStateFailure(msg) =>
        logUserAndMessage(user, s"Illegal state failure: $msg")
        Results.InternalServerError(msg)
      case ElasticSearchQueryFailure(throwable, responseCode, maybeResponseBody) =>
        val userMarker = user.map(_.asLogMarker)
        val responseMarker = maybeResponseBody.map(append("elasticsearchResponse", _))
        val markers = aggregate((userMarker ++ responseMarker).toList.asJava)

        logger.error(markers, "Elasticsearch query failure", throwable)

        maybeResponseBody match {
          case Some(responseBody) =>
            // Since we got a response body from elasticsearch, pass it straight through to client
            Results.Status(responseCode)(responseBody).as("application/json")

          case None =>
            Results.Status(responseCode)(throwable.toString)
        }
      case TransactionFailure(msg) =>
        logUserAndMessage(user, s"Transaction failure: $msg")
        Results.InternalServerError(msg)
      case AlreadySetupFailure(msg) =>
        logUserAndMessage(user, s"Already setup failure: $msg")
        Results.Conflict(msg)
      case neo4j: Neo4JFailure =>
        logUserAndMessage(user, s"Neo4J Failure ${neo4j.msg}")
        Results.InternalServerError(neo4j.msg)
      case neo4j: Neo4JTransientFailure =>
        logUserAndMessage(user, s"Neo4J Transient Failure ${neo4j.msg}")
        Results.InternalServerError(neo4j.msg)
      case neo4j: Neo4JValueFailure =>
        logUserAndMessage(user, s"Neo4J Value Failure ${neo4j.msg}")
        Results.InternalServerError(neo4j.msg)
      case aws: AwsSdkFailure =>
        logUserAndMessage(user, s"AWS Sdk Failure: ${aws.msg}")
        Results.InternalServerError(aws.msg)
      case unknown: UnknownFailure =>
        logUserAndMessage(user, s"Unknown Failure: ${unknown.msg}")
        Results.InternalServerError(unknown.msg)
      case externalTranscriptionOutputFailure: ExternalTranscriptionOutputFailure =>
        logUserAndMessage(user, s"externalTranscriptionOutputFailure Failure: ${externalTranscriptionOutputFailure.msg}")
        Results.InternalServerError(externalTranscriptionOutputFailure.msg)
      case documentUpdateFailure: DocumentUpdateFailure =>
        logUserAndMessage(user, s"documentUpdateFailure Failure: ${documentUpdateFailure.msg}")
        Results.InternalServerError(documentUpdateFailure.msg)
      case MissingPermissionFailure(msg) =>
        logUserAndMessage(user, s"Missing Permission Failure: $msg")
        Results.Forbidden(msg)
      case MultipleFailures(failures) => failureToResult(failures.head, user)
      case PreviewNotSupportedFailure =>
        logUserAndMessage(user, s"Preview Supported Failure")
        Results.NotAcceptable
      case SubprocessInterruptedFailure =>
        logUserAndMessage(user, s"Subprocess Interrupted Failure: ${SubprocessInterruptedFailure.msg}")
        Results.InternalServerError(SubprocessInterruptedFailure.msg)
      case ContentTooLongFailure(msg) =>
        logUserAndMessage(user, s"Content Too Long Failure: ${msg}")
        Results.EntityTooLarge(msg)
      case DeleteFailure(msg) =>
        logUserAndMessage(user, s"Delete failed: ${msg}")
        Results.InternalServerError(msg)
      case WorkspaceCopyFailure(msg) =>
        logUserAndMessage(user, s"Workspace copy failed: ${msg}")
        Results.InternalServerError(msg)
      case DeleteNotAllowed(msg) =>
        logUserAndMessage(user, s"Deletion is refused: ${msg}")
        Results.Forbidden(msg)
      case OcrTimeout(msg) =>
        logger.error(msg)
        Results.InternalServerError(msg)
      case f: PostgresWriteFailure =>
        logger.error(f.msg, f.throwable)
        Results.InternalServerError(f.msg)
      case f: PostgresReadFailure =>
        logger.error(f.msg, f.throwable)
        Results.InternalServerError(f.msg)
      case FfMpegFailure(error, message) =>
        logger.error(message)
        Results.InternalServerError(message)
    }
  }