-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds revert instruction handling #3248
Conversation
* @returns {Boolean} | ||
*/ | ||
Method.prototype.isRevertReasonString = function (data) { | ||
return _.isString(data) && ((data.length - 2) / 2) % 32 === 4 && data.substring(0, 10) === '0x08c379a0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
length = (data.length - 2); // exclude prefix
length = length / 2; // Transforming length to bytes length
argsCount = ((length % 32) === 4 ) // We have 4 arguments: signature, offset, length, data
isErrorSignature = data.substring(0, 10) === '0x08c379a0'; // The first 4 bytes are the Error signature
isRevertReasonString = (argsCount && isErrorSignature)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, just leaving a quick note. This looks really cool!
The are couple things that seem like breaking changes
- Throwing on eth_call
- Throwing with a different error message on eth_send
Additionally, I'm a little worried about additional server calls to fetch the reason since many wrappers or libs around Web3 are already doing that. In a contract testing context with lots error cases being run it could slow things down to duplicate this logic.
What do you think about making reason fetching available as an option that is toggled off by default and on via a new contract option?
Super interested in how eth_call
works as well...do you think it might be possible to spoof a 'revert' message for a call? Like if data can be set by a contract's users, they could set it so that on 'read', web3 would decode it as an error message and throw?
Thanks!:)
Sounds good to me but we have to be careful to not have too many configuration options because it could have a bad impact on the DX in the long run. I would also not have this only as a
I'm not sure if I understood you correctly. But you would like to have the revert instruction handling also for the bare |
…error removed in Method object
…ethod.send extended with severall revert test cases
… in e2e.method.send improved
@cgewecke I have added all the missing test cases and improved the solution I had with the During testing of the revert instruction handling did I notice that only module options which are defined before the Example: web3.eth.handleRevert = true;
contract = new web3.eth.Contract(..);
contract.methods.method(...).send(...); // works as expected
-----
contract = new web3.eth.Contract(..);
contract.handleRevert = true;
contract.methods.method(...).send(...); // doesn't work as expected Edit: I've added all new properties to the contract options with commit 9db572c. Example: contract = new web3.eth.Contract([], '0x...', {handleRevert: true, ...});
contract.methods.method(...).send(...); // does work as expected ToDo:
|
…ithout re-loading of the object methods
…ed documentation updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the fight about the error message, this LGTM.
WDYT about including test cases for?
web3.eth.call()
web3.eth.sendTransaction()
The test cases would be the same and would also test the same code. But I definitely can create a generic test helper for this and extend the test cases for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In summary, this review ends in approval from me, per the PR review guidelines proposed in #3224. AFAIK it doesn't violate any of the requirements.
(There's are a few dozen unnecessary lints that go against the idea of making the smallest number of changes required, but the core changes seem well-restricted in scope).
… object added to the documentation
@nivida Final note! This is really cool, Web3 might be the first lib to collect the revert string from Looked pretty safe to me as well - the length of the reason message is hard to replicate using conventional datatypes. |
Hi, error TS2322: Type 'TransactionRevertInstructionError | TransactionReceipt' is not assignable to type 'TransactionReceipt'. 57 const transactionReceipt:TransactionReceipt = await web3.eth.sendSignedTransaction(answer.rawTransaction) |
It looks like many of the promise types in web3-eth have mis-defined optional error types. Am opening an issue to correct this right now. If you don't specify the type of your variable (e.g. just let TS infer it) does everything work ok? const transactionReceipt = await web3.eth.sendSignedTransaction(answer.rawTransaction) |
Description
Fixes #176 #1903 #1707 #2197
This PR does implement revert instruction handling in the web3.js lib.
If the
handleRevert
options property is set totrue
you will get revert reasons on calling ofContract
object methods,sendTransaction
, andcall
of theeth
module. Those revert reasons will get returned to the user over the error listener (call
doesn't have a error event) or the catch handler if you are using the native Promise object.Error Interface
Type of change
Checklist:
npm run dtslint
with success and extended the tests and types if necessary.npm run test:unit
with success and extended the tests if necessary.npm run build-all
and tested the resulting file/'s fromdist
folder in a browser.CHANGELOG.md
file in the root folder.