I've made a new patch that includes a ReferenceInsertionEventHandler ("InvalidReferenceHandler") that collects a list of all invalid references in a Velocity page.
To see how it works, look at the test code (the last two methods) in BuiltInEventHandlerTestCase.
To make this work, I had to make some changes to the internals. So I thought I'd hold off a couple days before committing, let any interested parties comment.
There's a couple of interesting new pieces for plugin writers.
(1) In any user-defined plugin (event handlers, uberspectors, etc) you can now throw a subclass of VelocityRuntimeException (new exception). to signal unrecoverable states to the calling application. This runtime exception requires no change to the interface signature and is passed through the Velocity parsing process. (In the past, all Exceptions were caught and logged).
Example use: a custom uberspector or event handler that wishes to stop page processing. For example, the InvalidReferenceHandler can be configured to throw an exception at the first reference error.
(2) Event handlers can now receive information on the template name, line number, and column by implementing InfoAware. This only works for Local event handlers attached to a context (as opposed to the new Global type defined in Velocity properties).
Example use: InvalidReferenceHandler reports out the line,column, and template name of each reference error.
Everything is completely backwards compatible. It'd be simpler if it wasn't of course as they we could just redo the interfaces.