It depends on the scenario, but the biggest issue is security. When a developer throws an exception, they usually try to include some useful information in the message about what exactly went wrong. They cannot know if this information will be considered sensitive by you in the current context.
As an example, let's say you have a website with a login form. If the Users table was not in the database, and someone tried to log in, the exception created could be something like Unable to find table users in database MyDb (db.mysite.com)
If this message is displayed to an attacker, they now know where your database is and what db / table names are.
In this scenario, I try to register a complete exception with a unique identifier and display the identifier for the user, so that later I can follow me later if necessary.
Conversely, if it is a desktop application, then I am inclined to another - exception messages can help the end user (for example, Access Denied is something that the user can decide). Even then you are not sure that the exception message will be useful (ala Reference not set to an instance of an object ), so I tend to any exception inside the more useful one (for example, Unable to connect to database ) and expose a list of all internal exceptions. This means that the user receives an understandable message, but can also receive more useful information, if available, rather than a security risk.
Basic source share