Skip to content

Conversation

ppkarwasz
Copy link
Contributor

Historically, throwable pattern converters (%ex, %xEx, etc.) behaved in a context-sensitive way:

  • If the preceding formatter’s expansion did not end with whitespace, the converter automatically inserted a space before rendering the exception.

In version 2.25.0, this was changed to insert a newline instead of a space, but the behavior was still dependent on surrounding context.

What this change does

This PR removes the context-dependent behavior altogether and makes %ex expansion fully predictable, while remaining backward-compatible:

  • When %ex is added implicitly because alwaysWriteExceptions=true:

    • If the pattern already ends with %n, a plain %ex is appended.
    • Otherwise, %notEmpty{%n%ex} is appended. This ensures exceptions are always clearly separated from the main log message by a newline, without adding extra characters when no exception is present.
  • When %ex is explicitly included in the pattern by the user:

    • Its expansion is rendered exactly as written in the pattern.
    • It will never prepend a newline on its own.

Why

  • Eliminates confusing context-sensitive behavior.
  • Makes output consistent and predictable.
  • Preserves legacy expectations by only modifying implicitly added %ex.

Closes #3873

Historically, throwable pattern converters (`%ex`, `%xEx`, etc.) behaved in a context-sensitive way:

* If the **preceding formatter’s expansion** did not end with whitespace, the converter automatically inserted a space before rendering the exception.

In version `2.25.0`, this was changed to insert a **newline** instead of a space, but the behavior was still dependent on surrounding context.

#### What this change does

This PR removes the context-dependent behavior altogether and makes `%ex` expansion fully predictable, while remaining backward-compatible:

* When `%ex` is **added implicitly** because `alwaysWriteExceptions=true`:

  * If the pattern already ends with `%n`, a plain `%ex` is appended.
  * Otherwise, `%notEmpty{%n%ex}` is appended.
    This ensures exceptions are always clearly separated from the main log message by a newline, without adding extra characters when no exception is present.
* When `%ex` is **explicitly included** in the pattern by the user:

  * Its expansion is rendered exactly as written in the pattern.
  * It will **never** prepend a newline on its own.

#### Why

* Eliminates confusing context-sensitive behavior.
* Makes output consistent and predictable.
* Preserves legacy expectations by only modifying implicitly added `%ex`.

Closes #3873
@ppkarwasz ppkarwasz added this to the 2.25.2 milestone Sep 8, 2025
@ppkarwasz ppkarwasz merged commit c41feed into 2.x Sep 12, 2025
11 checks passed
@github-project-automation github-project-automation bot moved this from To triage to Done in Log4j bug tracker Sep 12, 2025
@ppkarwasz ppkarwasz deleted the fix/2.x/3873-throwable-converter branch September 12, 2025 11:00
@vy vy added the layouts Affects one or more Layout plugins label Sep 18, 2025
vy added a commit that referenced this pull request Sep 18, 2025
Historically, throwable pattern converters (`%ex`, `%xEx`, etc.) behaved in a context-sensitive way:

* If the **preceding formatter’s expansion** did not end with whitespace, the converter automatically inserted a space before rendering the exception.

In version `2.25.0`, this was changed to insert a **newline** instead of a space, but the behavior was still dependent on surrounding context.

#### What this change does

This PR removes the context-dependent behavior altogether and makes `%ex` expansion fully predictable, while remaining backward-compatible:

* When `%ex` is **added implicitly** because `alwaysWriteExceptions=true`:

  * If the pattern already ends with `%n`, a plain `%ex` is appended.
  * Otherwise, `%notEmpty{%n%ex}` is appended.
    This ensures exceptions are always clearly separated from the main log message by a newline, without adding extra characters when no exception is present.
* When `%ex` is **explicitly included** in the pattern by the user:

  * Its expansion is rendered exactly as written in the pattern.
  * It will **never** prepend a newline on its own.

#### Why

* Eliminates confusing context-sensitive behavior.
* Makes output consistent and predictable.
* Preserves legacy expectations by only modifying implicitly added `%ex`.

Closes #3873

Co-authored-by: Volkan Yazıcı <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

layouts Affects one or more Layout plugins

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Add support for old-style exception rendering in Pattern Layout

2 participants