mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Grammar and Documentation.
This commit is contained in:
parent
a66c354698
commit
a54d9d622f
@ -50,6 +50,12 @@ This section gives detailed instructions on how to update prior code for every b
|
|||||||
* Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be
|
* Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be
|
||||||
accessed via ``array.length``.
|
accessed via ``array.length``.
|
||||||
|
|
||||||
|
New Features
|
||||||
|
============
|
||||||
|
|
||||||
|
* The :ref:`try/catch statement <try-catch>` allows you to react on failed external calls.
|
||||||
|
|
||||||
|
|
||||||
Deprecated Elements
|
Deprecated Elements
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ Most of the control structures known from curly-braces languages are available i
|
|||||||
There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with
|
There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with
|
||||||
the usual semantics known from C or JavaScript.
|
the usual semantics known from C or JavaScript.
|
||||||
|
|
||||||
|
Solidity also supports exception handling in the form of ``try``/``catch``-statements,
|
||||||
|
but only for :ref:`external function calls <external-function-calls>` and
|
||||||
|
contract creation calls.
|
||||||
|
|
||||||
Parentheses can *not* be omitted for conditionals, but curly brances can be omitted
|
Parentheses can *not* be omitted for conditionals, but curly brances can be omitted
|
||||||
around single-statement bodies.
|
around single-statement bodies.
|
||||||
|
|
||||||
@ -383,7 +387,7 @@ of an exception instead of "bubbling up".
|
|||||||
.. warning::
|
.. warning::
|
||||||
The low-level functions ``call``, ``delegatecall`` and ``staticcall`` return ``true`` as their first return value if the account called is non-existent, as part of the design of EVM. Existence must be checked prior to calling if needed.
|
The low-level functions ``call``, ``delegatecall`` and ``staticcall`` return ``true`` as their first return value if the account called is non-existent, as part of the design of EVM. Existence must be checked prior to calling if needed.
|
||||||
|
|
||||||
It is not yet possible to catch exceptions with Solidity.
|
Exceptions can be caught with the ``try``/``catch`` statement.
|
||||||
|
|
||||||
``assert`` and ``require``
|
``assert`` and ``require``
|
||||||
--------------------------
|
--------------------------
|
||||||
@ -488,3 +492,94 @@ In the above example, ``revert("Not enough Ether provided.");`` returns the foll
|
|||||||
.. note::
|
.. note::
|
||||||
There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which
|
There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which
|
||||||
was deprecated in version 0.4.13 and removed in version 0.5.0.
|
was deprecated in version 0.4.13 and removed in version 0.5.0.
|
||||||
|
|
||||||
|
|
||||||
|
.. _try-catch:
|
||||||
|
|
||||||
|
``try``/``catch``
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
A failure in an external call can be caught using a try/catch statement, as follows:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pragma solidity >=0.5.0 <0.7.0;
|
||||||
|
|
||||||
|
interface DataFeed { function getData(address token) external returns (uint value); }
|
||||||
|
|
||||||
|
contract FeedConsumer {
|
||||||
|
DataFeed feed;
|
||||||
|
uint errorCount;
|
||||||
|
function rate(address token) public returns (uint value, bool success) {
|
||||||
|
// Permanently disable the mechanism if there are
|
||||||
|
// more than 10 errors.
|
||||||
|
require(errorCount < 10);
|
||||||
|
try feed.getData(token) returns (uint v) {
|
||||||
|
return (v, true);
|
||||||
|
} catch Error(string memory /*reason*/) {
|
||||||
|
// This is executed in case
|
||||||
|
// revert was called inside getData
|
||||||
|
// and a reason string was provided.
|
||||||
|
errorCount++;
|
||||||
|
return (0, false);
|
||||||
|
} catch (bytes memory /*lowLevelData*/) {
|
||||||
|
// This is executed in case revert() was used
|
||||||
|
// or there was a failing assertion, division
|
||||||
|
// by zero, etc. inside getData.
|
||||||
|
errorCount++;
|
||||||
|
return (0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The ``try`` keyword has to be followed by an expression representing an external function call
|
||||||
|
or a contract creation (``new ContractName()``).
|
||||||
|
Errors inside the expression are not caught (for example if it is a complex expression
|
||||||
|
that also involves internal function calls), only a revert happening inside the external
|
||||||
|
call itself. The ``returns`` part (which is optional) that follows declares return variables
|
||||||
|
matching the types returned by the external call. In case there was no error,
|
||||||
|
these variables are assigned and the contract's execution continues inside the
|
||||||
|
first success block. If the end of the success block is reached, execution continues after the ``catch`` blocks.
|
||||||
|
|
||||||
|
Currently, Solidity supports different kinds of catch blocks depending on the
|
||||||
|
type of error. If the error was caused by ``revert("reasonString")`` or
|
||||||
|
``require(false, "reasonString")`` (or an internal error that causes such an
|
||||||
|
exception), then the catch clause
|
||||||
|
of the type ``catch Error(string memory reason)`` will be executed.
|
||||||
|
|
||||||
|
It is planned to support other types of error data in the future.
|
||||||
|
The string ``Error`` is currently parsed as is and is not treated as an identifier.
|
||||||
|
|
||||||
|
The clause ``catch (bytes memory lowLevelData)`` is executed if the error signature
|
||||||
|
does not match any other clause, there was an error during decoding of the error
|
||||||
|
message, if there was a failing assertion in the external
|
||||||
|
call (for example due to a division by zero or a failing ``assert()``) or
|
||||||
|
if no error data was provided with the exception.
|
||||||
|
The declared variable provides access to the low-level error data in that case.
|
||||||
|
|
||||||
|
If you are not interested in the error data, you can just use
|
||||||
|
``catch { ... }`` (even as the only catch clause).
|
||||||
|
|
||||||
|
In order to catch all error cases, you have to have at least the clause
|
||||||
|
``catch { ...}`` or the clause ``catch (bytes memory lowLevelData) { ... }``.
|
||||||
|
|
||||||
|
The variables declared in the ``returns`` and the ``catch`` clause are only
|
||||||
|
in scope in the block that follows.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If an error happens during the decoding of the return data
|
||||||
|
inside a try/catch-statement, this causes an exception in the currently
|
||||||
|
executing contract and because of that, it is not caught in the catch clause.
|
||||||
|
If there is an error during decoding of ``catch Error(string memory reason)``
|
||||||
|
and there is a low-level catch clause, this error is caught there.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If execution reaches a catch-block, then the state-changing effects of
|
||||||
|
the external call have been reverted. If execution reaches
|
||||||
|
the success block, the effects were not reverted.
|
||||||
|
If the effects have been reverted, then execution either continues
|
||||||
|
in a catch block or the execution of the try/catch statement itself
|
||||||
|
reverts (for example due to decoding failures as noted above or
|
||||||
|
due to not providing a low-level catch clause).
|
@ -62,12 +62,14 @@ StorageLocation = 'memory' | 'storage' | 'calldata'
|
|||||||
StateMutability = 'pure' | 'view' | 'payable'
|
StateMutability = 'pure' | 'view' | 'payable'
|
||||||
|
|
||||||
Block = '{' Statement* '}'
|
Block = '{' Statement* '}'
|
||||||
Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
|
Statement = IfStatement | TryStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
|
||||||
( DoWhileStatement | PlaceholderStatement | Continue | Break | Return |
|
( DoWhileStatement | PlaceholderStatement | Continue | Break | Return |
|
||||||
Throw | EmitStatement | SimpleStatement ) ';'
|
Throw | EmitStatement | SimpleStatement ) ';'
|
||||||
|
|
||||||
ExpressionStatement = Expression
|
ExpressionStatement = Expression
|
||||||
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
|
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
|
||||||
|
TryStatement = 'try' Expression ( 'returns' ParameterList )? Block CatchClause+
|
||||||
|
CatchClause = 'catch' Identifier? ParameterList Block
|
||||||
WhileStatement = 'while' '(' Expression ')' Statement
|
WhileStatement = 'while' '(' Expression ')' Statement
|
||||||
PlaceholderStatement = '_'
|
PlaceholderStatement = '_'
|
||||||
SimpleStatement = VariableDefinition | ExpressionStatement
|
SimpleStatement = VariableDefinition | ExpressionStatement
|
||||||
|
Loading…
Reference in New Issue
Block a user