I wrote a custom function to catch errors in contract functions without executing a transaction. You can read the article here. https://medium.com/@Arslan_786/guide-to-simulating-ethereum-smart-contract-calls-with-web3-js-6d55cfa1550a