Skip to content

fix(rest): log 4xx client exceptions at WARN instead of ERROR - #1239

Merged
v1r3n merged 2 commits into
conductor-oss:mainfrom
gaurav0107:fix/1045-conductor-rest-logs-client-side-4xx-exce
Jul 10, 2026
Merged

v1r3n merged 2 commits into
conductor-oss:mainfrom
gaurav0107:fix/1045-conductor-rest-logs-client-side-4xx-exce

Conversation

@gaurav0107

Copy link
Copy Markdown
Contributor

Summary

ApplicationExceptionMapper in the rest module logged every exception at
ERROR via logException, including exceptions that map to 4xx client
responses — NotFoundException (404), ConflictException (409),
IllegalArgumentException (400), AccessForbiddenException (403),
NoResourceFoundException (404). These are expected, recoverable client-side
conditions that Conductor already handled correctly, so logging them at
ERROR pollutes server error logs and makes genuine 5xx server-side failures
harder to spot. For example, every attempt to create an already-existing
resource emits an ERROR entry even though the handled result is a 409.

This change computes the mapped HttpStatus before logging and selects the
log level from the status class:

  • 4xx client errors are logged at WARN
  • 5xx, and any unmapped exception (which falls back to 500), remain at ERROR

The status mapping, response body, and the Monitors.error(...) metric are
unchanged; only the log level for 4xx responses changes. The log message
template and argument order are identical in both branches, so existing log
parsing is unaffected.

Closes #1045

Tests

Extended ApplicationExceptionMapperTest (JUnit 4 + Mockito + MockMvc):

  • testException (generic Exception -> 500) is unchanged and still asserts
    ERROR-level logging.
  • testClientErrorLoggedAtWarn throws ConflictException (-> 409) and asserts
    the mapper returns 409 and logs at WARN, never ERROR.

logger is a shared static mock in this test class, so @Before now clears
its invocation history to keep the two tests order-independent.

The change was written against the source and hand-formatted to match the
module's existing googleJavaFormat().aosp() style; CI validates the build,
tests, and Spotless formatting.

ApplicationExceptionMapper logged every exception at ERROR, including
those mapped to 4xx client responses (NotFoundException -> 404,
ConflictException -> 409, and similar). These are expected, handled
client-side conditions; logging them at ERROR pollutes server error
logs and hides genuine 5xx server-side failures.

Compute the mapped HttpStatus before logging and emit 4xx at WARN,
reserving ERROR for 5xx and unmapped exceptions (which fall back to
500). Add a regression test asserting mapped 4xx responses (409 and
404) are logged at WARN, never ERROR, while the existing 500 test
continues to assert ERROR.

Closes conductor-oss#1045
@gaurav0107
gaurav0107 force-pushed the fix/1045-conductor-rest-logs-client-side-4xx-exce branch from 0b22a1e to 339ed81 Compare July 1, 2026 21:15
@gaurav0107
gaurav0107 marked this pull request as ready for review July 1, 2026 21:16
@v1r3n
v1r3n merged commit 55a458a into conductor-oss:main Jul 10, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants