Skip to content

[Console] Fix Multi-Line Error Message Format#7164

Merged
samsonasik merged 1 commit intorectorphp:mainfrom
FeBe95:patch-1
Aug 22, 2025
Merged

[Console] Fix Multi-Line Error Message Format#7164
samsonasik merged 1 commit intorectorphp:mainfrom
FeBe95:patch-1

Conversation

@FeBe95
Copy link
Contributor

@FeBe95 FeBe95 commented Aug 22, 2025

Fixes rectorphp/rector#9323.

Why is this necessary?

The PHP_EOL constant is used throughout the Rector source code to add newlines to error messages, that are forwarded to Symfony's Console component. On Windows, PHP_EOL resolves to \r\n. However, Symfony's console output formatter does not support \r\n line breaks. After calculating the width of the terminal window, it adds \n characters to the appropriate positions in the given message and splits the resulting string using \n as a separator. This leaves the affected lines with a trailing \r character, which breaks the console output.

Example

Let's take a look at the linked issue above as an example.

  1. Initially, the error message is defined as follows:
    $message = 'Pick only one version target in "withPhpSets()". All rules up to this version will be used.' . PHP_EOL . 'To use your composer.json > PHP version, keep arguments empty.';
  2. On Windows, this resolves to:
    $message = 'Pick only one version target in "withPhpSets()". All rules up to this version will be used.' . "\r\n" . 'To use your composer.json > PHP version, keep arguments empty.';
  3. Next, Symfony's output formatter calculates the terminal width and inserts zero or more \n characters at the appropriate positions where the message should be cut. For a rather small terminal window, the resulting string could look like this:
    $message = 'Pick only one version target in' . "\n" . '"withPhpSets()". All rules up to this' . "\n" . 'version will be used.' . "\r\n" . 'To use your composer.json > PHP version,' . "\n" . 'keep arguments empty.';
  4. The formatter now splits the string using \n, which results in these lines:
    $lines = [
        'Pick only one version target in',
        '"withPhpSets()". All rules up to this',
        "version will be used.\r", // <-- trailing `\r` char
        'To use your composer.json PHP version,',
        'keep arguments empty.'
    ];
  5. The trailing \r character in line 3 resets the cursor to the beginning of the line while outputting. Then, the output formatter prints the red padding characters (17x in this case). These characters overwrite the first 17 existing characters of the current line, including the beginning of the actual error message. The output is now broken.
    grafik

Solution

Sanitize all \r\n occurrences to simple \n characters:

  • The output isn't broken anymore, the error message is now perfectly legible:
    grafik

Screenshots

Below are some more screenshots, showing the "before" and "after" of the reported issue, using the original examples.

Wide

  • Before
    grafik
  • After
    grafik

Narrow

  • Before
    grafik
  • After
    grafik

Copy link
Member

@samsonasik samsonasik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍

@samsonasik samsonasik merged commit a5eb812 into rectorphp:main Aug 22, 2025
49 checks passed
@samsonasik
Copy link
Member

Thank you @FeBe95

@FeBe95 FeBe95 deleted the patch-1 branch August 22, 2025 13:07
@samsonasik
Copy link
Member

@FeBe95 could you add more fix on symfonyStyle->warning() as well? Thank you.

@FeBe95
Copy link
Contributor Author

FeBe95 commented Aug 23, 2025

@FeBe95 could you add more fix on symfonyStyle->warning() as well? Thank you.

Will do 👍

@github-actions
Copy link
Contributor

This pull request has been automatically locked because it has been closed for 150 days. Please open a new PR if you want to continue the work.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI Error Message Output Broken

2 participants