Chris@0: Error handling Chris@0: ============== Chris@0: Chris@0: Errors during parsing or analysis are represented using the `PhpParser\Error` exception class. In addition to an error Chris@0: message, an error can also store additional information about the location the error occurred at. Chris@0: Chris@0: How much location information is available depends on the origin of the error and how many lexer attributes have been Chris@0: enabled. At a minimum the start line of the error is usually available. Chris@0: Chris@0: Column information Chris@0: ------------------ Chris@0: Chris@0: In order to receive information about not only the line, but also the column span an error occurred at, the file Chris@0: position attributes in the lexer need to be enabled: Chris@0: Chris@0: ```php Chris@0: $lexer = new PhpParser\Lexer(array( Chris@0: 'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'), Chris@0: )); Chris@0: $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); Chris@0: Chris@0: try { Chris@0: $stmts = $parser->parse($code); Chris@0: // ... Chris@0: } catch (PhpParser\Error $e) { Chris@0: // ... Chris@0: } Chris@0: ``` Chris@0: Chris@13: Before using column information, its availability needs to be checked with `$e->hasColumnInfo()`, as the precise Chris@0: location of an error cannot always be determined. The methods for retrieving column information also have to be passed Chris@0: the source code of the parsed file. An example for printing an error: Chris@0: Chris@0: ```php Chris@0: if ($e->hasColumnInfo()) { Chris@0: echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code) Chris@0: . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code); Chris@0: // or: Chris@0: echo $e->getMessageWithColumnInfo(); Chris@0: } else { Chris@0: echo $e->getMessage(); Chris@0: } Chris@0: ``` Chris@0: Chris@0: 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: file. Chris@0: Chris@0: Error recovery Chris@0: -------------- Chris@0: Chris@0: The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is Chris@0: encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`, Chris@0: which will immediately throw when an error is encountered. Chris@0: Chris@0: To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code, Chris@0: an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example: Chris@0: Chris@0: ```php Chris@0: $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7); Chris@0: $errorHandler = new PhpParser\ErrorHandler\Collecting; Chris@0: Chris@0: $stmts = $parser->parse($code, $errorHandler); Chris@0: Chris@0: if ($errorHandler->hasErrors()) { Chris@0: foreach ($errorHandler->getErrors() as $error) { Chris@0: // $error is an ordinary PhpParser\Error Chris@0: } Chris@0: } Chris@0: Chris@0: if (null !== $stmts) { Chris@0: // $stmts is a best-effort partial AST Chris@0: } Chris@0: ``` Chris@0: Chris@0: The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument.