如何捕获 withSizeLimit 指令抛出的 EntityStreamSizeException

问题描述 投票:0回答:1

我在 akka http 中创建了一个 post 请求来上传文件

这是我的代码

final val MEDIA_FILE_UPLOAD_MAX_SIZE = 30 * 1024 * 1024

def uploadMediaObjectForASite(): Route = path("Some path") {
  userId =>
    post {
      parameter(Symbol("location_id").as[String]) {
        locationId =>
          withSizeLimit(MEDIA_FILE_UPLOAD_MAX_SIZE) {
            withRequestTimeout(120.seconds) {
              entity(as[Multipart.FormData]) {
                formData =>
                  val metadataList = List(TITLE, DESCRIPTION, UPLOADED_BY)
                  // extract file parts and start the upload process
              }
            }
          }
      }
    }
}

如果我使用大于 30MB 的文件,我会在邮递员中收到 400 BadRequest 并显示以下消息

EntityStreamSizeException:传入实体大小(47350868)超出大小限制(31457280 字节)!这可能是解析器限制(通过

akka.http.[server|client].parsing.max-content-length
设置)、解码器限制(通过
akka.http.routing.decode-max-size
设置)或使用
withSizeLimit
设置的自定义限制。

我尝试过以下方法 a) 使用handleException指令

 val customExceptionHandler: ExceptionHandler = ExceptionHandler {
    case _: EntityStreamSizeException =>
      complete(StatusCodes.PayloadTooLarge, "File size exceeded the limit of 30MB")
  }

def uploadMediaObjectForASite(): Route = path("Some path") {
  userId =>
    post {
        handleException(customExceptionHandler) {
            parameter(Symbol("location_id").as[String]) {
            locationId =>
              withSizeLimit(MEDIA_FILE_UPLOAD_MAX_SIZE) {
                withRequestTimeout(120.seconds) {
                  entity(as[Multipart.FormData]) {
                    formData =>
                      val metadataList = List(TITLE, DESCRIPTION, UPLOADED_BY)
                      // extract file parts and start the upload process
                  }
                }
              }
          }
        }
    }
}

b) 使用handleRejection指令

val customRejectionHandler: RejectionHandler = RejectionHandler.newBuilder()
    .handle {
      case EntityStreamSizeException(limit, actualSize) =>
        complete(StatusCodes.PayloadTooLarge, s"File size exceeded the limit of ${limit} bytes")
    }
    .result()

def uploadMediaObjectForASite(): Route = path("Some path") {
  userId =>
    post {
        handleRejection(customRejectionHandler) {
            parameter(Symbol("location_id").as[String]) {
            locationId =>
              withSizeLimit(MEDIA_FILE_UPLOAD_MAX_SIZE) {
                withRequestTimeout(120.seconds) {
                  entity(as[Multipart.FormData]) {
                    formData =>
                      val metadataList = List(TITLE, DESCRIPTION, UPLOADED_BY)
                      // extract file parts and start the upload process
                  }
                }
              }
          }
        }
    }
}

但是它们都不起作用

如何捕获此异常并提供自定义消息。

scala akka-http
1个回答
0
投票

您需要为

handleExceptions()
/
handleRejections()
添加指令
exceptionHandler
/
rejectionHandler
才能工作,例如:

  val handleErrors = handleExceptions(customExceptionHandler) &  handleRejections(customRejectionHandler)

  val routes: Route = {
    handleErrors {
      concat(uploadMediaObjectForASite, myOtherRoute)
    }
  }

另请参阅此工作示例

© www.soinside.com 2019 - 2024. All rights reserved.