DRAFT: Proposed syntax and initial documentation for error type.

This commit is contained in:
Christian Parpart 2020-04-22 09:47:32 +02:00
parent 325a78fe47
commit 8f744c1d0d
2 changed files with 102 additions and 1 deletions

View File

@ -8,7 +8,8 @@
grammar Solidity;
sourceUnit
: (pragmaDirective | importDirective | structDefinition | enumDefinition | contractDefinition)* EOF ;
: (pragmaDirective | importDirective | structDefinition | enumDefinition | contractDefinition |
errorDefinition)* EOF ;
pragmaDirective
: 'pragma' pragmaName pragmaValue ';' ;
@ -51,6 +52,7 @@ contractPart
| modifierDefinition
| functionDefinition
| eventDefinition
| errorDefinition
| enumDefinition ;
stateVariableDeclaration
@ -92,6 +94,10 @@ modifierInvocation
eventDefinition
: 'event' identifier eventParameterList AnonymousKeyword? ';' ;
errorDefinition : 'error' identifier errorParameterList ';' ;
errorParameterList : '(' (errorParameter (',' errorParameter)*)? ')' ;
errorParameter : typeName identifier? ;
enumDefinition
: 'enum' identifier '{' enumValue? (',' enumValue)* '}' ;
@ -167,6 +173,9 @@ tryStatement : 'try' expression returnParameters? block catchClause+ ;
// leave this as is, befitting with the Solidity docs.
catchClause : 'catch' ( identifier? parameterList )? block ;
catchClauseNEW : 'catch' errorTypeName parameterList block ;
errorTypeName : identifier ;
whileStatement
: 'while' '(' expression ')' statement ;

92
docs/error-type.md Normal file
View File

@ -0,0 +1,92 @@
# Solidity `error` type
## Motivation
We want to support typed errors in a syntactically equivalent and convenient way like
the programmer can define `event` types.
Example:
```solidity
contract C {
event HighestBidIncreased(address bidder, uint amount);
error BiddingFailed(string reason);
function bid() public payable {
try attemptBid() {
emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
} catch BiddingFailed(reason) {
// handle error with given reason
}
}
function attemptBid() {
// require() should now support a custom secondary parameter to throw custom errors upon failed expectations.
require(biddingPossible, BiddingFailed("Bidding impossible"));
}
}
```
## Syntax
```bnf
errorDefinition
: 'error' identifier eventParameterList AnonymousKeyword? ';' ;
```
## Semantic
Errors can be instantiated wherever a variable of a type can be declared.
Errors can NOT be instantiated like any arbitrary type, but instead only be used
within `require` and `revert`.
Error types are ALWAYS publicly visible, i.e. they can not be made private.
## Catching Errors
With the try-catch statement, you can already catch `Error(string)`. This will be extended
to catch errors by other structured types that were declared via the `error` keyword.
The fallback catch will also apply to error types that weren't matched.
Example:
```solidity
contract C {
event HighestBidIncreased(address bidder, uint amount);
error BiddingFailed(string reason);
error SomeOtherError(string text, uint value);
function bid() public payable {
try attemptBid() {
emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
} catch BiddingFailed(string reason) {
// handle error with given reason
} catch SomeOtherError(string reason, uint value) {
// handle other error with an additional value
} catch Error(string message) {
// handle classic error messages
} catch (bytes data) {
// parametrized default
}
}
}
```
## The current `Error(string message)` type.
Currently, exceptions can be caught via `catch Error(string text)`. This behaviour will be retained
by providing the default error type `Error`.
## Code Generation
Whatever ABI encoder is selected, this one will be used to encode/decode the error in
require/revert/catch.