We had a big discussion about whether we should use exceptions or just have a thin wrapper over the C interface of TurboActivate. We ended up using exceptions because it fits with the nature of the languages (and the performance loss is so small as to be non-existent).
2) The exceptions are all implemented in a flat hierarchy. This is not very convenient if all exceptions should be caught in one place and only some of the need special treatment (all others will be handled equally). I think it would be good to have e.g. GeneralTurboActivateException as base and then derive all other exceptions from it.
You're right -- the exceptions should share a common base 1 level higher than "Exception". We'll fix this for TA 3.2 or 3.3. Thanks for suggesting that.
3) Many exception messages can be shown e.g. within an GUI to the user without any security concerns, but there is one, which is named GUIDMismatchException and seems problematic to me, because its message contains the product GUID ("The version GUID \"" + TurboActivate.VersionGUID + "\" doesn't match that of the product details file. Make sure you set the GUID using TurboActivate.VersionGUID."). It could be replayed by e.g. "The product details file "TurboActivate.dat" does not match the product." like I've now done within our product.
We used to have something like what you're suggesting. The problem is that it's confusing for new users just trying out LimeLM.
Plus, in production you should eat that exception no matter what wording we use. Does that make sense?