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