You should avoid iterating the list of permitted accounts. It's an expensive approach that doesn't scale and it has a lot of moving parts.
Consider instead using a mapping. This is a namespace where all the uninitialized indexes return false, 0, empty, depending on type. For example:
mapping(address => bool) public whitelist; returns true or false for ...
I recommend that you look at the OpenZeppelin guide on Access Control, specifically the section on Role-Based Access Control as using Roles from OpenZeppelin appear to meet your needs.
For questions on use, you can also ask in the community forum https://forum.zeppelin.solutions/
You are making a fundamental mistake which makes it all seem much harder than it really is.
Instead of an array, your should use a mapping(address => bool), let's call it whitelisted.
Add people in the whitelist like this: whitelisted[_address] = true;
then in your modifier, you can simply do this:
Read operations you can put behind a regular API as you get the result instantly. As for write operations, you can expose an API which has something like "initiateFunctionA" and another operation which returns the results when it's ready but you shouldn't keep the API call hanging waiting for the result to the write operation - it may take a while (or even ...
Short answer is that you can't see revert messages in etherscan.io.
If you can reproduce this on ganache, ganache will provide the revert message.
Beyond that you'd have to share the code, or even better verify it on etherscan (Ropsten) if you wanted help debugging.
Metamask is a browser extension. More info: https://metamask.io
It is not used in node.js or server side implementation. For server side, you have to unlock accounts using private keys, etc.
Sample code for browser side ...