The problem is, I think that even with AOP you cannot intercept the process of consuming exceptions. With AOP, you can capture, say, all the exceptions that were created, but you cannot know when they will be consumed.
For instance:
try { ... } catch (Exception e) { log.boom("Ouchies happened here", e); }
Not every exception is re-selected.
However, at a certain MOST level, an ARE exception was eventually thrown so that the caller could handle them.
So, given that you are most likely to "console" the exceptions, the game should try to find the "leaks" of the exceptions.
Using AOP, you can get away from each Exception as it is created (whether you can do it at the Exception level or do it at the level of a separate class, I canβt say - you are not familiar with AOP in practice in this case).
As soon as you throw exceptions when they are thrown, you start calling processing methods through AOP. When you do this, you can catch the exceptions thrown by the method.
So, with a little work, you know when you return from method a) which exceptions were thrown and b) which were thrown. If you throw an exception "caused" by the tree of the returned exception from the method, you can drop it from the list of "exceptions created by this method". The rest are leaks.
Ideally, after a little analysis, you can determine which ones are simply not thrown away (but handled in some other way) and which ones are actually obscured by your finally blocks.
This is imperfect, and, of course, I would not use it in production (I just would have to work a lot in all the conditions of the race around the record, etc. More work than I would like to do for this kind of debugging, to be honest). But it can give you the information you are looking for, especially if it is rarely used in a small class domain.