it seems to me that you have swapped croak and carp! croak dies, carp just prints warnings.
Anyway, usually, talking directly to the end user about some internals of the program is not a good idea... well, for scripts it is ok, specially if you are both the user and the programmer but for modules it's a bad idea, it doesn't escalate.
For most errors, the best think to do is to croak() and let the module user wrap the call in eval if he wants to handle the error in some way or just ignore it.
Sometimes, returning false and passing more information about the error in $! also makes sense.