Skip to content

Commit f23e1f8

Browse files
MTDSA-32420 - Return 504 GATEWAY_TIMEOUT for 499s and 504s from downstream (#152)
1 parent f4203c7 commit f23e1f8

File tree

4 files changed

+23
-5
lines changed

4 files changed

+23
-5
lines changed

app/api/models/errors/CommonMtdErrors.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ object InternalError extends MtdError("INTERNAL_SERVER_ERROR", "An internal serv
105105

106106
object BadRequestError extends MtdError("INVALID_REQUEST", "Invalid request", BAD_REQUEST)
107107

108+
object GatewayTimeoutError extends MtdError("GATEWAY_TIMEOUT", "The request has timed out", GATEWAY_TIMEOUT)
109+
108110
object BVRError extends MtdError("BUSINESS_ERROR", "Business validation error", BAD_REQUEST)
109111

110112
object ServiceUnavailableError extends MtdError("SERVICE_UNAVAILABLE", "Internal server error", INTERNAL_SERVER_ERROR)

app/utils/ErrorHandler.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ class ErrorHandler @Inject() (
9797
ex
9898
)
9999

100+
val NGINX_TIMEOUT = 499
101+
val timeoutStatusCodes: Set[Int] = Set(NGINX_TIMEOUT, GATEWAY_TIMEOUT)
102+
100103
val (errorCode, eventType) = ex match {
101-
case _: NotFoundException => (NotFoundError, "ResourceNotFound")
102-
case _: AuthorisationException => (ClientOrAgentNotAuthorisedError.withStatus401, "ClientError")
103-
case _: JsValidationException => (BadRequestError, "ServerValidationError")
104-
case e: HttpException => (BadRequestError, "ServerValidationError")
104+
case _: NotFoundException => (NotFoundError, "ResourceNotFound")
105+
case _: AuthorisationException => (ClientOrAgentNotAuthorisedError.withStatus401, "ClientError")
106+
case _: JsValidationException => (BadRequestError, "ServerValidationError")
107+
case e: HttpException => (BadRequestError, "ServerValidationError")
108+
case e: UpstreamErrorResponse if timeoutStatusCodes.contains(e.statusCode) => (GatewayTimeoutError, "ServerTimeoutError")
105109
case e: UpstreamErrorResponse if UpstreamErrorResponse.Upstream4xxResponse.unapply(e).isDefined =>
106110
(BadRequestError, "ServerValidationError")
107111
case e: UpstreamErrorResponse if UpstreamErrorResponse.Upstream5xxResponse.unapply(e).isDefined =>

project/AppDependencies.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import sbt.*
1818

1919
object AppDependencies {
2020

21-
val bootstrapPlayVersion = "9.18.0"
21+
val bootstrapPlayVersion = "9.19.0"
2222

2323
val compile: Seq[ModuleID] = List(
2424
"uk.gov.hmrc" %% "bootstrap-backend-play-30" % bootstrapPlayVersion,

test/utils/ErrorHandlerSpec.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ class ErrorHandlerSpec extends UnitSpec with GuiceOneAppPerSuite {
157157
contentAsJson(result) shouldBe InternalError.asJson
158158
}
159159
}
160+
161+
"return GATEWAY_TIMEOUT with error body" when {
162+
Seq(499, GATEWAY_TIMEOUT).foreach { statusCode =>
163+
s"a $statusCode UpstreamErrorResponse is returned" in new Test {
164+
val errorResponse: UpstreamErrorResponse = UpstreamErrorResponse("request timeout", statusCode, statusCode, Map.empty)
165+
val result: Future[Result] = handler.onServerError(requestHeader, errorResponse)
166+
167+
status(result) shouldBe GATEWAY_TIMEOUT
168+
contentAsJson(result) shouldBe GatewayTimeoutError.asJson
169+
}
170+
}
171+
}
160172
}
161173

162174
def anyVersionHeader: (String, String) = ACCEPT -> s"application/vnd.hmrc.1.0+json"

0 commit comments

Comments
 (0)