codeconsole opened a new pull request, #15564:
URL: https://github.com/apache/grails-core/pull/15564
## Fix duplicate stack trace logging in DefaultStackTraceFilterer
When an exception occurs in a Grails controller, the same error is logged
multiple times to the `StackTrace` logger. For a typical
`InvocationTargetException` wrapping a `RuntimeException`, this produces
3-4 separate ERROR log entries for a single request:
1. `StackTrace` logger: Full stack trace of the wrapper exception
2. `StackTrace` logger: Full stack trace of the root cause
3. `StackTrace` logger: Full stack trace of the wrapper again (condensed)
4. `GrailsExceptionResolver` logger: The exception with request context
Entries 1-3 all come from `DefaultStackTraceFilterer.filter()`. The
`filter(Throwable source, boolean recursive)` method walks the
cause chain and calls `filter(Throwable source)` for each throwable. But
`filter(Throwable source)` logs the full stack trace via
`STACK_LOG.error(FULL_STACK_TRACE_MESSAGE, source)` every time it trims a
trace — so each cause in the chain gets its own log entry.
This is compounded by the fact that
`GrailsExceptionResolver.logStackTrace()` then logs the exception a final time
with request
context. The filterer and the resolver were written independently — the
filterer doesn't know the resolver will also log, and the
resolver doesn't know the filterer already logged.
### Fix
Extract the stack trace trimming logic into a private
`doFilter(Throwable)` method that filters without logging. The recursive walk
calls `doFilter()` for each cause in the chain. The public
`filter(Throwable source)` method calls `doFilter()` and then logs the
full stack trace **once** for the top-level exception (which naturally
includes its causes in the log output).
This reduces the `StackTrace` logger output from N entries (one per cause)
to 1 entry, while preserving all existing behavior:
- Stack traces are still recursively filtered for all causes
- The full unfiltered trace is still logged before trimming (for debugging)
- The `StackTraceFilterer` interface is unchanged
- Custom `GrailsExceptionResolver` subclasses are unaffected
- All existing tests pass without modification
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]