>For example, the various flavors of Microsoft Basics have the "On>Error Goto" construct and the Err object.

If you have the .NET SDK at hand, you can find out how On Error is
handled, using try-catch blocks.

In general a line-reference is required which is adjusted at runtime,
at the begin of the code for every source line. When a runtime error
occurs, then the error handler can determine from that reference,
where to continue on Resume or Resume Next.

In the old (non-MSIL) implementation the compiler created the
instructions to set the line index, and a table with line
number/address pairs. Almost all error handling was done in the
runtime system, up to the invocation of the user supplied error
handler.

In the MSIL approach the new error filters are used, which IMO were
"invented" exactly for the handling of the VB On Error
construct. Every protected section of code, starting with On Error,
corresponds to an filter which checks the line number, where the error
occured, and signals the exception handling system to invoke the
according exception handler. The exception handler initializes the
data structures which are used in VB code to handle the error, and
then jumps to that code. Every Resume statement is redirected to
another compiler-generated piece of code, which uses a switch
instruction to jump to the line where execution shall resume.

The MSIL specification states that it's allowed to "leave" an
exception handler to any place in the according Try block. This would
simplify the design, so that everything could be done in the error
handler, including the Resume at the appropriate place. There may
exist reasons why the compiler doesn't use that feature. Perhaps it's
for the handling of further exceptions, which can be raised during the
execution of the user supplied error handler?

IMO the Basic error handling philosophy is appropriate only for
interpreters, since the implementation will disallow almost any
optimization during compilation of such code.