Why do you say that a sub containing exit is a red flag?
Don't use exit to abort a subroutine if there's any chance that someone might want to trap whatever error happened. Use die instead, which can be trapped by an eval.
Think of a subroutine as a server providing a service to its clients (callers). It’s up to the client to decide how to handle the information returned by its server. Even an exception (thrown by die) is information which the client can use or ignore as desired. The server should never preempt the client in determining how to proceed.
Hope that helps,
Athanasius <°(((>< contra mundum