I have written this function:
// Function to get an owned token's id by referencing the index of the user's owned tokens.
// ex: user has 5 tokens, tokenOfOwnerByIndex(owner,3) will give the id of the 4th token.
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint _tokenId) {
// TODO: Make sure this works. Does not appear to throw when _index<balanceOf(_owner), which violates
// ERC721 compatibility.
assert(_index<balanceOf(_owner)); // throw if outside range
return ownedTokenIds[_owner][_index];
}
When run with an _index of 2 and an _owner such that balanceOf(_owner) is 0, the function returns a 0 in the Remix IDE. My assumption was that it would not return anything. My questions are:
A) Why does it return a 0 after failing an assert?
B) How do I get this to not return a 0 when I run it with the above parameters?
Thanks, Vaughn
Deleting my other answer as it was incorrect.
Error handling conditions are not bubbled up to the client in view
functions. They are only used to revert state changing transactions on the blockchain. For view
functions, the processing will stop and the initial 0 value of the specified return type is returned (0 for uint
, false for bool
, etc).
As a result, error handling for view
functions has to be handled on the client. If you need to be able to differentiate between a valid 0 return value vs an error, you would do something like this:
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint, bool) {
bool success = _index < balanceOf(_owner);
return (ownedTokenIds[_owner][_index], success);
}