The
caller of pcall is responsible for propagating the errors however it sees fit (by raising an exception with error(), passing the error object around, or local handling). The Lua core and standard library rarely raise exceptions themselves-- most errors are signaled by return arguments. As far as the message handler of xpcall, it's not an error handler as you call it, but apparently a way to expand or translate the exception object in flight which will eventually be returned to the caller of xpcall.
Given your recent posts, I think you'd gain from the Lua Gems chapter I wrote, "Exceptions in Lua". It covers error handling, why using inline functions as a poor-man's scope less than ideal, exception safety (i.e. finalization), and scope managers. There's even a footnote that declares hooking of scope exit as the last fundamental building block missing from Lua :)