fix: display full error messages instead of truncated table output#72
fix: display full error messages instead of truncated table output#72jordanpartridge wants to merge 1 commit intomasterfrom
Conversation
Replace Laravel Prompts table() with line-by-line output so long error messages are no longer truncated. Closes #63.
📝 WalkthroughWalkthroughThe CertifyCommand failure display was refactored from a table format to individual formatted lines to eliminate truncation of long error messages. Two new tests validate that complete error messages from multiple checks display without truncation. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📊 Coverage Report
Files Below Threshold
🏆 Synapse Sentinel Gate |
🔧 Synapse Sentinel: 2 checks need attentionThe following issues must be resolved before this PR can be merged: All tests passed.--- Security AuditReview the output and fix any issues.Quick Reference:
🤖 Generated by Synapse Sentinel - View Run |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/Commands/CertifyCommand.php`:
- Around line 148-152: The console output is injecting unescaped dynamic values
from failureRows ($row[0], $row[1]) into a formatted string, which lets any
"<...>" sequences be interpreted as Symfony formatting tags; fix it by escaping
both values with Symfony\Component\Console\Formatter\OutputFormatter::escape()
(or equivalent escape helper available in CertifyCommand) before interpolating
them into the styled $this->line call so the red/white styling remains but the
content is printed verbatim.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 981724e8-9643-425b-905c-6329cbceac58
📒 Files selected for processing (2)
app/Commands/CertifyCommand.phptests/Unit/Commands/CertifyCommandTest.php
| $this->newLine(); | ||
| foreach ($failureRows as $row) { | ||
| $this->line(" <fg=red>✗</> <fg=white;options=bold>{$row[0]}</>: {$row[1]}"); | ||
| } | ||
| $this->newLine(); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and read the CertifyCommand.php file
find . -name "CertifyCommand.php" -type fRepository: synapse-sentinel/gate
Length of output: 98
🏁 Script executed:
# Read the CertifyCommand.php file, focusing on the area around lines 148-152
wc -l ./app/Commands/CertifyCommand.phpRepository: synapse-sentinel/gate
Length of output: 102
🏁 Script executed:
cat -n ./app/Commands/CertifyCommand.php | sed -n '130,170p'Repository: synapse-sentinel/gate
Length of output: 1875
🏁 Script executed:
# Now let me find where $failureRows is populated
cat -n ./app/Commands/CertifyCommand.php | head -150 | tail -50Repository: synapse-sentinel/gate
Length of output: 2321
🏁 Script executed:
# Search for failureRows initialization/population
grep -n "failureRows" ./app/Commands/CertifyCommand.phpRepository: synapse-sentinel/gate
Length of output: 259
🏁 Script executed:
# Let me see the full context around lines 71 and 94 where failureRows is created/populated
cat -n ./app/Commands/CertifyCommand.php | sed -n '65,100p'Repository: synapse-sentinel/gate
Length of output: 1567
🏁 Script executed:
# Let me find where CheckResult or similar is defined to understand what $result->details contains
find . -name "*.php" -type f | xargs grep -l "class.*Check\|interface.*Check" | head -10Repository: synapse-sentinel/gate
Length of output: 375
🏁 Script executed:
# Also, let me look at the runCheck method to understand the result structure
cat -n ./app/Commands/CertifyCommand.php | sed -n '170,234p'Repository: synapse-sentinel/gate
Length of output: 2297
🏁 Script executed:
# Let me examine the CheckResult class to understand what $details contains
cat -n ./app/Checks/CheckResult.phpRepository: synapse-sentinel/gate
Length of output: 796
🏁 Script executed:
# Let me check the various Check implementations to see what data goes into details
cat -n ./app/Checks/SecurityScanner.php | head -100Repository: synapse-sentinel/gate
Length of output: 2330
🏁 Script executed:
# Also check TestRunner
cat -n ./app/Checks/TestRunner.php | head -100Repository: synapse-sentinel/gate
Length of output: 4064
🏁 Script executed:
# Continue reading TestRunner to see parseFailureDetails implementation
cat -n ./app/Checks/TestRunner.php | sed -n '100,180p'Repository: synapse-sentinel/gate
Length of output: 2103
🏁 Script executed:
# Let me check if OutputFormatter is already used in the codebase
grep -r "OutputFormatter" ./app --include="*.php"Repository: synapse-sentinel/gate
Length of output: 47
🏁 Script executed:
# Also check what PestOutputParser returns for parseFailures to understand the content better
cat -n ./app/Services/PestOutputParser.php | head -80Repository: synapse-sentinel/gate
Length of output: 3304
🏁 Script executed:
# Let me check what dependencies are available, particularly Symfony
cat composer.json | grep -A 20 '"require"'Repository: synapse-sentinel/gate
Length of output: 555
🏁 Script executed:
# Also check if there are any console-related imports in CertifyCommand
head -30 ./app/Commands/CertifyCommand.phpRepository: synapse-sentinel/gate
Length of output: 926
🏁 Script executed:
# Check if symfony/console is available as a transitive dependency
cat composer.lock | grep -A 5 '"name": "symfony/console"'Repository: synapse-sentinel/gate
Length of output: 328
🏁 Script executed:
# Also verify what base class CertifyCommand extends and where line() comes from
grep -r "class Command" ./app --include="*.php" -A 5Repository: synapse-sentinel/gate
Length of output: 47
🏁 Script executed:
# Search for escape or sanitize patterns in the codebase
grep -r "escape\|sanitize\|htmlspecialchars" ./app --include="*.php"Repository: synapse-sentinel/gate
Length of output: 47
Escape dynamic failure text before writing styled console output.
At line 150, $row[0] and $row[1] are injected directly into a formatted console string. These values originate from external sources: check names, package names from composer audit JSON, test failure messages from Pest output, and file paths. If any contain <...> patterns, Symfony's OutputFormatter will parse them as formatting tags, potentially stripping or altering content and breaking error visibility.
Proposed fix
+use Symfony\Component\Console\Formatter\OutputFormatter;
...
$this->newLine();
foreach ($failureRows as $row) {
- $this->line(" <fg=red>✗</> <fg=white;options=bold>{$row[0]}</>: {$row[1]}");
+ $checkName = OutputFormatter::escape((string) $row[0]);
+ $detail = OutputFormatter::escape((string) $row[1]);
+ $this->line(" <fg=red>✗</> <fg=white;options=bold>{$checkName}</>: {$detail}");
}
$this->newLine();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $this->newLine(); | |
| foreach ($failureRows as $row) { | |
| $this->line(" <fg=red>✗</> <fg=white;options=bold>{$row[0]}</>: {$row[1]}"); | |
| } | |
| $this->newLine(); | |
| $this->newLine(); | |
| foreach ($failureRows as $row) { | |
| $checkName = OutputFormatter::escape((string) $row[0]); | |
| $detail = OutputFormatter::escape((string) $row[1]); | |
| $this->line(" <fg=red>✗</> <fg=white;options=bold>{$checkName}</>: {$detail}"); | |
| } | |
| $this->newLine(); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/Commands/CertifyCommand.php` around lines 148 - 152, The console output
is injecting unescaped dynamic values from failureRows ($row[0], $row[1]) into a
formatted string, which lets any "<...>" sequences be interpreted as Symfony
formatting tags; fix it by escaping both values with
Symfony\Component\Console\Formatter\OutputFormatter::escape() (or equivalent
escape helper available in CertifyCommand) before interpolating them into the
styled $this->line call so the red/white styling remains but the content is
printed verbatim.
Problem
Laravel Prompts
table()function truncates long error messages at column width limits (~140 characters), making it impossible for users to debug test failures.Root Cause
File:
app/Commands/CertifyCommand.php:149-152The
table()function formats output in fixed-width columns, causing truncation like:Solution
table()import and call$this->line()✗ CheckName: full error messageTesting
Added regression test with 260+ character error message to verify full display without truncation.
Impact
Closes #63
Summary by CodeRabbit
Release Notes