Chris@0
|
1 Error handling
|
Chris@0
|
2 ==============
|
Chris@0
|
3
|
Chris@0
|
4 Errors during parsing or analysis are represented using the `PhpParser\Error` exception class. In addition to an error
|
Chris@0
|
5 message, an error can also store additional information about the location the error occurred at.
|
Chris@0
|
6
|
Chris@0
|
7 How much location information is available depends on the origin of the error and how many lexer attributes have been
|
Chris@0
|
8 enabled. At a minimum the start line of the error is usually available.
|
Chris@0
|
9
|
Chris@0
|
10 Column information
|
Chris@0
|
11 ------------------
|
Chris@0
|
12
|
Chris@0
|
13 In order to receive information about not only the line, but also the column span an error occurred at, the file
|
Chris@0
|
14 position attributes in the lexer need to be enabled:
|
Chris@0
|
15
|
Chris@0
|
16 ```php
|
Chris@0
|
17 $lexer = new PhpParser\Lexer(array(
|
Chris@0
|
18 'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'),
|
Chris@0
|
19 ));
|
Chris@0
|
20 $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
|
Chris@0
|
21
|
Chris@0
|
22 try {
|
Chris@0
|
23 $stmts = $parser->parse($code);
|
Chris@0
|
24 // ...
|
Chris@0
|
25 } catch (PhpParser\Error $e) {
|
Chris@0
|
26 // ...
|
Chris@0
|
27 }
|
Chris@0
|
28 ```
|
Chris@0
|
29
|
Chris@13
|
30 Before using column information, its availability needs to be checked with `$e->hasColumnInfo()`, as the precise
|
Chris@0
|
31 location of an error cannot always be determined. The methods for retrieving column information also have to be passed
|
Chris@0
|
32 the source code of the parsed file. An example for printing an error:
|
Chris@0
|
33
|
Chris@0
|
34 ```php
|
Chris@0
|
35 if ($e->hasColumnInfo()) {
|
Chris@0
|
36 echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code)
|
Chris@0
|
37 . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code);
|
Chris@0
|
38 // or:
|
Chris@0
|
39 echo $e->getMessageWithColumnInfo();
|
Chris@0
|
40 } else {
|
Chris@0
|
41 echo $e->getMessage();
|
Chris@0
|
42 }
|
Chris@0
|
43 ```
|
Chris@0
|
44
|
Chris@0
|
45 Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the
|
Chris@0
|
46 file.
|
Chris@0
|
47
|
Chris@0
|
48 Error recovery
|
Chris@0
|
49 --------------
|
Chris@0
|
50
|
Chris@0
|
51 The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is
|
Chris@0
|
52 encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`,
|
Chris@0
|
53 which will immediately throw when an error is encountered.
|
Chris@0
|
54
|
Chris@0
|
55 To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code,
|
Chris@0
|
56 an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example:
|
Chris@0
|
57
|
Chris@0
|
58 ```php
|
Chris@0
|
59 $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7);
|
Chris@0
|
60 $errorHandler = new PhpParser\ErrorHandler\Collecting;
|
Chris@0
|
61
|
Chris@0
|
62 $stmts = $parser->parse($code, $errorHandler);
|
Chris@0
|
63
|
Chris@0
|
64 if ($errorHandler->hasErrors()) {
|
Chris@0
|
65 foreach ($errorHandler->getErrors() as $error) {
|
Chris@0
|
66 // $error is an ordinary PhpParser\Error
|
Chris@0
|
67 }
|
Chris@0
|
68 }
|
Chris@0
|
69
|
Chris@0
|
70 if (null !== $stmts) {
|
Chris@0
|
71 // $stmts is a best-effort partial AST
|
Chris@0
|
72 }
|
Chris@0
|
73 ```
|
Chris@0
|
74
|
Chris@0
|
75 The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument. |