This is the code that gives that error. I'm trying to learn how to create a token and this is where I'm stuck.
if(!_spender.call(bytes4(bytes32(sha3(“receiveApproval(address,uint256,address,bytes)”))), msg.sender, _value, this, _extraData)) { throw; } return true;
Related
I have an internal function
function _somefunction() internal {
if (address(attr) != address(0)) {
try attr.maybedoesntexist() {
} catch Error(string memory message) {
emit SomethingFailed();
} catch {
emit SomethingFailed();
}
}
}
When I test this in hardhat I set attr to be a non-contract, but somehow the error function call to a non-contract account goes through the first catch and the whole thing reverts.
No other function uses attr and the error is completely dependent on whether attr is a contract account. Can catch actually not handle some errors?
Exceptions from calls to non-contracts are currently (v0.8) not caught by try/catch.
You can validate whether the address is a contract, and only invoke calls on contracts:
// length of attr's bytecode is 0, it's not a contract
if (address(attr).code.length == 0) {
return;
}
try attr.maybedoesntexist() {
I've just wrote a controller class in a Blazor application and I don't undersand something.
I have a method GetEmployee:
[HttpGet("{employeeId:int}")]
public async Task<ActionResult<Employee>> GetEmployee(int employeeId)
{
try
{
var result = await employeeRepsitory.GetEmployee(employeeId);
if (result == null)
{
NotFound();
}
return result;
}
catch (Exception)
{
return StatusCode(StatusCodes.Status500InternalServerError,
"Error retrieving data from the database");
}
}
The return type is an ActionResult<Employee> but clearly in my method I'm returning an Employee. Because the employeeRepsitory.GetEmployee(employeeId) method gives back a single Employee which is stored in a variable "result".
I have an other method GetEmployees :
[HttpGet]
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployees()
{
try
{
return Ok(await employeeRepsitory.GetEmployees());
}
catch (Exception)
{
return StatusCode(StatusCodes.Status500InternalServerError,
"Error retrieving data from the database");
}
}
Where I put my object in an Ok() ActionResult. If I didn't wrap await employeeRepsitory.GetEmployees() in an Ok() then I have compillation error because I'm not giving back ActionResult. But how does that GetEmployee(int employeeId) method is not giving me compilation error yet I'm clearly giving back an Employee object and not an ActionResult. Thank you for your answers.
I'm new in kotlin world. So I have some problem. I'm using ktor framework and try to use ktor-locations (https://ktor.io/servers/features/locations.html#route-classes)
And as example
#Location("/show/{id}")
data class Show(val id: Int)
routing {
get<Show> { show ->
call.respondText(show.id)
}
}
Everything is good, when I try to get /show/1
But if route will be /show/test there is NumberFormatException, cause DefaultConversionService try to convert id to Int and can't do it.
So my question is, how can I catch this exception and return Json with some error data. For example, if not using locations I can do smt like this
routing {
get("/{id}") {
val id = call.parameters["id"]!!.toIntOrNull()
call.respond(when (id) {
null -> JsonResponse.failure(HttpStatusCode.BadRequest.value, "wrong id parameter")
else -> JsonResponse.success(id)
})
}
}
Thx for help!
You can do a simple try-catch in order to catch the parsing exception which is thrown when a string can not be converted to an integer.
routing {
get("/{id}") {
val id = try {
call.parameters["id"]?.toInt()
} catch (e : NumberFormatException) {
null
}
call.respond(when (id) {
null -> HttpStatusCode.BadRequest
else -> "The value of the id is $id"
})
}
}
Other way of handling exception is to use StatusPages module:
install(StatusPages) {
// catch NumberFormatException and send back HTTP code 400
exception<NumberFormatException> { cause ->
call.respond(HttpStatusCode.BadRequest)
}
}
This should work with using Location feature. Please note that Location is experimental above ktor version 1.0.
Optional<BigDecimal> maybeConvertStringToBigDecimal(Optional<String> string) {
string.flatMap {
try {
return Optional.of(new BigDecimal(it))
} catch (Exception e) {
log.error "Exception: ${e.message}\n\n${e.stackTrace}"
return Optional.<BigDecimal> empty()
}
}
}
This code compiles just fine but IntelliJ shows a red warning that
Cannot return 'Optional<U>' from method returning
'Optional<BigDecimal>'
I think it is clear that there is always Optional<BigDecimal> returned. What can be done to get rid of the warning? Is this an IntelliJ issue or is there an issue with the code?
Let's start with my solidity code :
pragma solidity ^0.4.18;
contract Voting {
address mainAddress;
bytes32[] candidateNames;
mapping(bytes32 => uint) candidateVotes;
mapping(bytes32 => bytes32) candidatesDetails;
address[] voters;
function Voting() public {
mainAddress = msg.sender;
}
modifier isMainAddress {
if (msg.sender == mainAddress) {
_;
}
}
function getAllCandidates() public view returns (bytes32[]) {
return candidateNames;
}
function setCandidate(bytes32 newCandidate) isMainAddress public {
candidateNames.push(newCandidate);
}
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
function getVote(bytes32 candidate) public view returns (uint) {
return candidateVotes[candidate];
}
function setDescrption(bytes32 candidateName, bytes32 candidatesDesc) isMainAddress public {
candidatesDetails[candidateName] = candidatesDesc;
}
function getDescription(bytes32 candidateName) public view returns (bytes32){
return candidatesDetails[candidateName];
}
function getCurrentAddress() public view returns (address) {
return msg.sender;
}
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
}
The functions : Voting(), getAllCandidates(), setCandidate(), getVote(), setDescription(), getDescription(), getCurrentAddress() works fine when called multiple times. So, I guess we can ignore them for now.
The function setVote() runs fine the first time it executes ie. when a person votes for once. The problem arises when the same person tries to vote the second time. It gives the following error :
This might be a beginners mistake but I have been trying to fix this for 2 days straight and now I really need help.
Also,
I use Remix - browser based IDE to run/check my solidity code.
I use Ganache for test accounts.
Thanks.
The function in question:
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
Note that validVoters() must return true for this function to succeed. If it returns false, the require will fail and revert the transaction. Also note that at the end of the function, msg.sender is added to the array voters.
Let's take a look at validVoters():
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
This function returns false if msg.sender is in voters, which we know will be the case after the account has voted once.
So the second time through, validVoters() returns false, which causes require(validVoters()) in setVote() to revert the transaction.