views:

324

answers:

4

I have this Perl software that is supposed to run 24/7. It keeps open a connection to an IMAP server, checks for new mail and then classifies new messages.

Now I have a user that is hibernating his XP laptop every once in a while. When this happens, the connection to the server fails and an exception is triggered. The calling code usually catches that exception and tries to reconnect. But in this case, it seems that Windows (or Perl?) is catching the exception and delivering it to the user via a message box.

Anyone know how I can prevent that kind of wtf? Could my code catch a "system-is-about-to-hibernate" signal?

To clear up some points you already raised:

  • I have no problem with users hibernating their machines. I just need to find a way to deal with that.
  • The Perl module in question does throw an exception. It does something like "die 'foo bar'. Although the application is completely browser based and doesn't use anything like Wx or Tk, the user gets a message box titled "poll_timer". The content of that message box is exactly the contents of $@ ('foo bar' in this example).
  • The application is compiled into an executable using perlapp. The documentation doesn't mention anything about exception handling, though.
A: 

Your user is not the exception but rather the rule. My laptop is hibernated between work and home. At work, it is on on DHCP network; at home, it is on another altogether. Most programs continue to work despite a confusing multiplicity of IP addresses (VMWare, VPN, plain old connection via NAT router). Those that don't (AT&T Net Client, for the VPN - unused in the office, necessary at home or on the road) recognize the disconnect at hibernate time (AT&T Net Client holds up the StandBy/Hibernate process until it has disconnected), and I re-establish the connection if appropriate when the machine wakes up. At airports, I use the local WiFi (more DHCP) but turn of the wireless altogether (one physical switch) before boarding the plane.

So, you need to find out how to learn that the machine is going into StandBy or Hibernation mode for your software to be usable. What I don't have, I'm sorry to say, is a recipe for what you need to do.

Some work with Google suggests that ACPI (Advanced Configuration and Power Interface) is part of the solution (Microsoft). APM (Advanced Power Management) may also be relevant.

Jonathan Leffler
A: 

It's difficult to offer intelligent suggestions without seeing relevant bits of code. If you're getting a dialog box with an exception message the program is most likely using either the Tk or wxPerl GUI library, which may complicate things a bit. With that said, my guess would be that it would be pretty easy to modify the exception handling in the program by wrapping the failure point in an eval block and testing $@ after the call. If $@ contains an error message indicating connection failure, then re-establish the connection and go on your way.

converter42
I am neither using Tk nor Wx. The app is completely browser-based. That's exactly why I am a bit clueless about that message box. My app doesn't know how to produce message boxes.
innaM
+1  A: 

I think that you're dealing with an OS-level exception, not something thrown from Perl. The relevant Perl module is making a call to something in a DLL (I presume), and the exception is getting thrown. Your best bet would be to boil this down to a simple, replicable test case that triggers the exception (you might have to do a lot of hibernating and waking the machines involved for this process). Then, send this information to the module developer and ask them if they can come up with a means of catching this exception in a way that is more useful for you.

If the module developer can't or won't help, then you'll probably wind up needing to use the Perl debugger to debug into the module's code and see exactly what is going on, and see if there is a way you can change the module yourself to catch and deal with the exception.

skiphoppy
The good news is that I am the developer of the Perl module. The bad news is that the exception is really thrown by Perl, but must somehow get promoted to the OS level.
innaM
If it's thrown by Perl (and not by a DLL you're interacting with through Perl, including C code compiled for the Perl module into a DLL), then it should be a cinch to catch it. Wrap it in eval.
skiphoppy
It IS wrapped in an eval!
innaM
In that case I'm really having trouble believe this is genuinely a Perl exception, and not a Windows thing. Can you boil the thing down to a short independent test case that throws the exception? What are you calling in that test case? Windows code?
skiphoppy
I sympathize. The problem is that I have currently no way to test on Windows. But it all really boils down to eval { do_some_networking() or die }; I guess that the machine hibernates while doing the networking.
innaM
Manni, if you are a module author, then you need to check out [this news](http://use.perl.org/~Alias/journal/38036)
skiphoppy
Yepp. I was hoping to get my hands on this one of these days.
innaM
A: 

I've found a hack to avoid modal system dialog boxes for hard errors (e.g. "encountered and exception and needs to close"). I don't know if the same trick will work for this kind of error you're describing, but you could give it a try.

See: Avoiding the “encountered a problem and needs to close” dialog on Windows

In short, set the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ErrorMode registry key to the value “2″.

xdg