The two possibilities "Error" and "array" are the only ones which can occur "spontanously". You will never get anything else unless you throw something else yourself. So it's basically a case of "don't do that then". It's up to the application if you want to use strange throw values or not.
But still, I hardly write all the code I use myself.
And then again, with the current situation I still have to take into account the 2 options when handling an error, _every_ time I handle an error. I still think this causes more overhead than necessary. For instance if I just want to display the error message and nothing else.
If what you are requesting is backwards incompatible changes to throw and/or catch, you will hardly meet much approval here. It is, however, widely agreed upon that current exception handling in Pike has _a lot_ of improvement potential (the gentle way of stating that it sucks, and that we agree it is substandard to what many other languages offer).
One of the current system's big warts is, as you note, that the code you have to write to catch errors you did not plan for receiving, and inspect or process their data, _smells really bad_. Ways forward from that are of course of general interest, and good ideas about how to tackle that issue will probably be well received. (If you are content with a single method that converts random errors to a human readable string, describe_error might be enough for you.)
I believe that, regarding improvements and behaviour changes to the raw throw/catch construct, most of the pike core developers now have rather high standards for what will be good enough to be implemented, if we do change them -- which means that kludges to them to make the status quo feel slightly less bothersome will likely not meet much approval here, nor exert any changes to happen spontaneously.
If you want to improve on the status quo, coming up with some nice support method or class to put in the Error module might be a good spot to focus your attention on, so you could write code similar to this, perhaps (and I don't claim it's good design; just a possible starting point for further discussion and improvements):
Error e = Error.inspect(catch(...)); // returns falsity for catch()=>0 if (e) { if (has_prefix(e->message, "Division by zero")) { // ... } // other goodies you want to see conveniently available - and how }
And, while that suggestion too has all sorts of flaws, I think it is a better starting point than your present line of enquiry; discussion does not seem to move forward anywhere productive.