I have created a post request in akka http to upload a file
Here is my code
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
}
}
}
}
}
}
If I use a file greater than 30MB I get a 400 BadRequest in postman with following message
EntityStreamSizeException: incoming entity size (47350868) exceeded size limit (31457280 bytes)! This may have been a parser limit (set via
akka.http.[server|client].parsing.max-content-length
), a decoder limit (set viaakka.http.routing.decode-max-size
), or a custom limit set withwithSizeLimit
.
I have tried following approach a) using handleException directive
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) using handleRejection directive
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
}
}
}
}
}
}
}
But none of them works
How can I catch this exception and provide custom message.
You may use the directives handleExceptions()
/handleRejections()
like this:
val handleErrors = handleExceptions(customExceptionHandler) & handleRejections(customRejectionHandler)
val routes: Route = {
handleErrors {
concat(uploadMediaObjectForASite, myOtherRoute)
}
}
Also see this working example. Not sure why your approach is not working though, although I just see the handleExceptions
directive in 10.5.2 (and not handleException
). Also I see that the response PayloadTooLarge
is deprecated in favour of ContentTooLarge
.