Commit 55748f8e authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #733 from ethereum/fixTxResult

refactor vm error check
parents 42b5e163 be7e0531
'use strict' 'use strict'
var yo = require('yo-yo')
module.exports = { module.exports = {
/** /**
...@@ -29,5 +30,33 @@ module.exports = { ...@@ -29,5 +30,33 @@ module.exports = {
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case) // see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback(error, txResult) callback(error, txResult)
}) })
},
/**
* check if the vm has errored
*
* @param {Object} txResult - the value returned by the vm
* @return {Object} - { error: true/false, message: DOMNode }
*/
checkVMError: function (txResult) {
var ret = {
error: false,
message: ''
}
if (!txResult.result.vm.exceptionError) {
return ret
}
var error = yo`<span> VM error: ${txResult.result.vm.exceptionError}</span>`
var msg
if (txResult.result.vm.exceptionError === 'invalid opcode') {
msg = yo`<ul><li>The constructor should be payable if you send it value.</li>
<li>The execution might have thrown.</li></ul>`
ret.error = true
} else if (txResult.result.vm.exceptionError === 'out of gas') {
msg = yo`<div>The transaction ran out of gas. Please increase the Gas Limit.</div>`
ret.error = true
}
ret.message = yo`<div>${error} ${msg} Debug the transaction to get more information</div>`
return ret
} }
} }
...@@ -304,8 +304,13 @@ function contractDropdown (appAPI, appEvents, instanceContainer) { ...@@ -304,8 +304,13 @@ function contractDropdown (appAPI, appEvents, instanceContainer) {
txExecution.createContract(data, appAPI.udapp(), (error, txResult) => { txExecution.createContract(data, appAPI.udapp(), (error, txResult) => {
if (!error) { if (!error) {
var isVM = appAPI.executionContext().isVM() var isVM = appAPI.executionContext().isVM()
if (isVM && alertVMErrorIfAny(txResult)) return if (isVM) {
var vmError = txExecution.checkVMError(txResult)
if (vmError.error) {
modalDialogCustom.alert(vmError.message)
return
}
}
noInstancesText.style.display = 'none' noInstancesText.style.display = 'none'
var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
instanceContainer.appendChild(appAPI.udapp().renderInstance(contract, address, selectContractNames.value)) instanceContainer.appendChild(appAPI.udapp().renderInstance(contract, address, selectContractNames.value))
...@@ -319,22 +324,6 @@ function contractDropdown (appAPI, appEvents, instanceContainer) { ...@@ -319,22 +324,6 @@ function contractDropdown (appAPI, appEvents, instanceContainer) {
}) })
} }
function alertVMErrorIfAny (txResult) {
if (!txResult.result.vm.exceptionError) {
return null
}
var error = yo`<span> VM error: ${txResult.result.vm.exceptionError}</span>`
var msg
if (txResult.result.vm.exceptionError === 'invalid opcode') {
msg = yo`<ul><li>The constructor should be payable if you send it value.</li>
<li>The execution might have thrown.</li></ul>`
} else if (txResult.result.vm.exceptionError === 'out of gas') {
msg = yo`<div>The transaction ran out of gas. Please increase the Gas Limit.</div>`
}
modalDialogCustom.alert(yo`<div>${error} ${msg} Debug the transaction to get more information</div>`)
return error + msg
}
function loadFromAddress (appAPI) { function loadFromAddress (appAPI) {
noInstancesText.style.display = 'none' noInstancesText.style.display = 'none'
var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
......
/* global alert */ /* global */
'use strict' 'use strict'
var $ = require('jquery') var $ = require('jquery')
...@@ -13,6 +13,7 @@ var txFormat = require('./app/execution/txFormat') ...@@ -13,6 +13,7 @@ var txFormat = require('./app/execution/txFormat')
var txHelper = require('./app/execution/txHelper') var txHelper = require('./app/execution/txHelper')
var txExecution = require('./app/execution/txExecution') var txExecution = require('./app/execution/txExecution')
var helper = require('./lib/helper') var helper = require('./lib/helper')
var modalDialogCustom = require('./app/ui/modal-dialog-custom')
// copy to copyToClipboard // copy to copyToClipboard
const copy = require('clipboard-copy') const copy = require('clipboard-copy')
...@@ -309,17 +310,25 @@ UniversalDApp.prototype.getCallButton = function (args) { ...@@ -309,17 +310,25 @@ UniversalDApp.prototype.getCallButton = function (args) {
if (!error) { if (!error) {
txExecution.callFunction(args.address, data, args.funABI, self, (error, txResult) => { txExecution.callFunction(args.address, data, args.funABI, self, (error, txResult) => {
if (!error) { if (!error) {
var isVM = self.executionContext.isVM()
if (isVM) {
var vmError = txExecution.checkVMError(txResult)
if (vmError.error) {
modalDialogCustom.alert(vmError.message)
return
}
}
if (lookupOnly) { if (lookupOnly) {
txFormat.decodeResponse(self.executionContext.isVM() ? txResult.result.vm.return : ethJSUtil.toBuffer(txResult.result), args.funABI, (error, decoded) => { txFormat.decodeResponse(self.executionContext.isVM() ? txResult.result.vm.return : ethJSUtil.toBuffer(txResult.result), args.funABI, (error, decoded) => {
$outputOverride.html(error ? 'error' + error : decoded) $outputOverride.html(error ? 'error' + error : decoded)
}) })
} }
} else { } else {
alert(error) modalDialogCustom.alert(error)
} }
}) })
} else { } else {
alert(error) modalDialogCustom.alert(error)
} }
}) })
} }
...@@ -436,6 +445,17 @@ UniversalDApp.prototype.runTx = function (args, cb) { ...@@ -436,6 +445,17 @@ UniversalDApp.prototype.runTx = function (args, cb) {
if (!args.useCall) { if (!args.useCall) {
self.event.trigger('transactionExecuted', [error, args.to, args.data, false, result]) self.event.trigger('transactionExecuted', [error, args.to, args.data, false, result])
} }
if (error) {
if (typeof (error) !== 'string') {
if (error.message) {
error = error.message
} else {
try {
error = 'error: ' + JSON.stringify(error)
} catch (e) {}
}
}
}
callback(error, result) callback(error, result)
}) })
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment