Error_handling.markdown 2.7 KB
Newer Older
N
Nikita Popov 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Error handling
==============

Errors during parsing or analysis are represented using the `PhpParser\Error` exception class. In addition to an error
message, an error can also store additional information about the location the error occurred at.

How much location information is available depends on the origin of the error and how many lexer attributes have been
enabled. At a minimum the start line of the error is usually available.

Column information
------------------

In order to receive information about not only the line, but also the column span an error occurred at, the file
position attributes in the lexer need to be enabled:

```php
$lexer = new PhpParser\Lexer(array(
    'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'),
));
N
Nikita Popov 已提交
20
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
N
Nikita Popov 已提交
21 22 23 24 25 26 27 28 29

try {
    $stmts = $parser->parse($code);
    // ...
} catch (PhpParser\Error $e) {
    // ...
}
```

30
Before using column information, its availability needs to be checked with `$e->hasColumnInfo()`, as the precise
N
Nikita Popov 已提交
31 32 33 34 35 36 37
location of an error cannot always be determined. The methods for retrieving column information also have to be passed
the source code of the parsed file. An example for printing an error:

```php
if ($e->hasColumnInfo()) {
    echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code)
        . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code);
N
Nikita Popov 已提交
38
    // or:
39
    echo $e->getMessageWithColumnInfo($code);
N
Nikita Popov 已提交
40 41 42 43 44
} else {
    echo $e->getMessage();
}
```

N
Nikita Popov 已提交
45
Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the
N
Nikita Popov 已提交
46 47 48 49 50
file.

Error recovery
--------------

N
Nikita Popov 已提交
51 52 53
The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is
encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`,
which will immediately throw when an error is encountered.
N
Nikita Popov 已提交
54

N
Nikita Popov 已提交
55 56
To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code,
an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example:
N
Nikita Popov 已提交
57 58

```php
N
Nikita Popov 已提交
59 60
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7);
$errorHandler = new PhpParser\ErrorHandler\Collecting;
N
Nikita Popov 已提交
61

N
Nikita Popov 已提交
62
$stmts = $parser->parse($code, $errorHandler);
N
Nikita Popov 已提交
63

N
Nikita Popov 已提交
64 65 66 67
if ($errorHandler->hasErrors()) {
    foreach ($errorHandler->getErrors() as $error) {
        // $error is an ordinary PhpParser\Error
    }
N
Nikita Popov 已提交
68 69 70 71 72 73 74
}

if (null !== $stmts) {
    // $stmts is a best-effort partial AST
}
```

75
The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument.