Skip to content

Commit

Permalink
Merge pull request #829 from derekmd/handle-eval-syntax-errors
Browse files Browse the repository at this point in the history
[2.x] Handle all eval() failures from Laravel Tinker
  • Loading branch information
taylorotwell authored Feb 18, 2020
2 parents 005f998 + 48e54e7 commit 14c679b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/ExceptionContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Laravel\Telescope;

use Illuminate\Support\Str;
use Throwable;

class ExceptionContext
Expand All @@ -13,6 +14,33 @@ class ExceptionContext
* @return array
*/
public static function get(Throwable $exception)
{
return static::getEvalContext($exception) ??
static::getFileContext($exception);
}

/**
* Get the exception code context when eval() failed.
*
* @param \Throwable $exception
* @return array|null
*/
protected static function getEvalContext(Throwable $exception)
{
if (Str::contains($exception->getFile(), "eval()'d code")) {
return [
$exception->getLine() => "eval()'d code",
];
}
}

/**
* Get the exception code context from a file.
*
* @param \Throwable $exception
* @return array
*/
protected static function getFileContext(Throwable $exception)
{
return collect(explode("\n", file_get_contents($exception->getFile())))
->slice($exception->getLine() - 10, 20)
Expand Down
31 changes: 30 additions & 1 deletion tests/Watchers/ExceptionWatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

namespace Laravel\Telescope\Tests\Watchers;

use ErrorException;
use Exception;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Laravel\Telescope\EntryType;
use Laravel\Telescope\Tests\FeatureTestCase;
use Laravel\Telescope\Watchers\ExceptionWatcher;
use ParseError;

class ExceptionWatcherTest extends FeatureTestCase
{
Expand Down Expand Up @@ -34,10 +36,37 @@ public function test_exception_watcher_register_entries()
$this->assertSame(EntryType::EXCEPTION, $entry->type);
$this->assertSame(BananaException::class, $entry->content['class']);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(28, $entry->content['line']);
$this->assertSame(30, $entry->content['line']);
$this->assertSame('Something went bananas.', $entry->content['message']);
$this->assertArrayHasKey('trace', $entry->content);
}

public function test_exception_watcher_register_entries_when_eval_failed()
{
$handler = $this->app->get(ExceptionHandler::class);

$exception = null;

try {
eval('if (');

$this->fail('eval() was expected to throw "syntax error, unexpected end of file"');
} catch (ParseError $e) {
// PsySH class ExecutionLoopClosure wraps ParseError in an exception.
$exception = new ErrorException($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
}

$handler->report($exception);

$entry = $this->loadTelescopeEntries()->first();

$this->assertSame(EntryType::EXCEPTION, $entry->type);
$this->assertSame(ErrorException::class, $entry->content['class']);
$this->assertStringContainsString("eval()'d code", $entry->content['file']);
$this->assertSame(1, $entry->content['line']);
$this->assertSame('syntax error, unexpected end of file', $entry->content['message']);
$this->assertArrayHasKey('trace', $entry->content);
}
}

class BananaException extends Exception
Expand Down

0 comments on commit 14c679b

Please sign in to comment.