A strategy to use would be the following (assuming your APEX is sending one (1) email message; adapt code for more than one accordingly. The key is the method `Messaging.reserveSingleEmailCapacity(someInteger)` that you invoke before you send.

 Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
 try {
 Messaging.reserveSingleEmailCapacity(1); // SFDC throws exception if no headroom
 email.setToAddresses(...);
 ...
 Messaging.sendEmail(email);
 }
 catch (HandledException e) {
 // do something interesting like set up a retry mechanism for the next day
 // by persisting the message to send in some object and then having a daily
 // scheduled job resend the message at 0000h
 }

There is [a related post on this topic][1] by @DougB
 

> UPDATE
> 
> Prior to Winter 14, the `reserveMassEmailCapacity` existed but would
> throw an unhandled exception, this changed as per the Winter 14
> Release Notes page 304
> 
> 
> 
> Updated Errors for Email Messaging Methods Errors have changed for the
> Apex Messaging methods reserveMassEmailCapacity and
> reserveSingleEmailCapacity, which are used when sending a mass or
> single email, respectively. If the transaction would cause the
> organization to exceed its daily email limit, using either of these
> methods results in a Handled Exception error. (Previously it resulted
> in a Limit Exception error.) The error that appears is:
> System.HandledException: The daily limit for the org would be exceeded
> by this request.

 

[1]: https://salesforce.stackexchange.com/a/17140/2602