Your expectation is that Mail::IMAPClient is using
die or equivalent when it runs into errors, creating a trappable error.
Your description of what is happening leads me to suspect that Mail::IMAPClient is just warning, which writes to STDERR (and therefore goes to foo.err) and leaves no trapped error (hence the "connected successfully" message).
If my suspicion is correct, then you can get what you want with the line:
$SIG{__WARN__} = sub {die @_};
so that warnings become dies and get caught like you expect.
But note that if STDERR is being written to directly (eg with "print STDERR") then you'll have to put in a lot more effort.