Skip to content

Commit 305bfd9

Browse files
fix(http4s): keep raw 400 for Old-Style versions in ErrorResponseConverter
`resolveStatusCode` was promoting any 400 with an OBP-XXXXX prefix to the canonical status code via `ErrorMessages.getCodeByOBPPrefix` (403 for UserNoPermissionAccessView, etc.). That broke v1.2.1's 4 "view doesn't exist" / "missing token" / "user lacks privileges" tests in API1_2_1Test that assert 400, because Old-Style versions (v1.x, v2.0.0) never promote to 401/403 — they return 400 for every error per the long-standing OBP convention (same set ResourceDocMiddleware.authenticate honours). Guard the translation with the same oldStyleShortVersions set so v1.2.1 gets 400 and v2.1.0+ still gets the canonical code (DoubleEntryTransaction v4 test still passes with 403 for UserNoPermissionAccessView). Verified: API1_2_1Test 323/323 pass, DoubleEntryTransactionTest 4/4 pass.
1 parent 0281423 commit 305bfd9

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

obp-api/src/main/scala/code/api/util/http4s/ErrorResponseConverter.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,29 @@ object ErrorResponseConverter {
8585
}
8686
}
8787

88+
/** Old-style versions keep raw 400 codes — they never promote to 403/401/etc.
89+
* Mirrors the same set used in ResourceDocMiddleware.authenticate.
90+
*/
91+
private val oldStyleShortVersions = Set("v1.2.1", "v1.3.0", "v1.4.0", "v2.0.0")
92+
8893
/**
8994
* Translate a 400 default with an OBP-prefixed message to the canonical status
9095
* Lift assigns (403 for role/view-access codes, 401 for auth codes, etc.) via
9196
* ErrorMessages.getCodeByOBPPrefix. Leaves non-400 failCodes (caller set
92-
* status explicitly) untouched.
97+
* status explicitly) untouched. Old-style versions (v1.x, v2.0.0) keep the
98+
* 400 — they return 400 for every error per the long-standing OBP convention.
9399
*/
94-
private def resolveStatusCode(failCode: Int, failMsg: String): Int =
95-
if (failCode == 400) code.api.util.ErrorMessages.getCodeByOBPPrefix(failMsg)
100+
private def resolveStatusCode(failCode: Int, failMsg: String, callContext: CallContext): Int =
101+
if (failCode == 400 && !oldStyleShortVersions.contains(callContext.implementedInVersion))
102+
code.api.util.ErrorMessages.getCodeByOBPPrefix(failMsg)
96103
else failCode
97104

98105
/**
99106
* Convert APIFailureNewStyle to http4s Response.
100107
* Uses failCode as HTTP status and failMsg as error message.
101108
*/
102109
def apiFailureToResponse(failure: APIFailureNewStyle, callContext: CallContext): IO[Response[IO]] = {
103-
val resolvedCode = resolveStatusCode(failure.failCode, failure.failMsg)
110+
val resolvedCode = resolveStatusCode(failure.failCode, failure.failMsg, callContext)
104111
val errorJson = OBPErrorResponse(resolvedCode, failure.failMsg)
105112
val status = org.http4s.Status.fromInt(resolvedCode).getOrElse(org.http4s.Status.BadRequest)
106113
IO.pure(

0 commit comments

Comments
 (0)