What is the "correct" way of reporting problems detected by sanity checks, or catching exceptions? Example I:
You do something with Entity API, which sometimes throws an EntityMalformedException. So you wrap it into a try/catch block. You develop a fallback behavior, but you also want the admin to know that something is wrong.

Example II:
You expect that a specific field on a node is mandatory. There is a block that only works correctly if this field is set, and not empty. You develop a fallback behavior for the case that the field is empty, but you also want to let the admin know that something is wrong.

Example III:
A file you need is not readable. You develop a safe fallback behavior, but also want to let the admin know that something is wrong.

So far what I came up with is to do two things, plus the fallback:


Call watchdog($module, $message, array(), WATCHDOG_WARNING).
Call drupal_set_message($message, 'warning'), if the user has user_access('administer site configuration'). Regular users will not see this message.
Move on with a safe fallback behavior. E.g. if we cannot render a specific block, we just return an empty block. If we cannot load an image, we show a placeholder image. Etc.


What I see in other parts of Drupal 7 is that corrupt data can travel quite far, without being checked, before something blows up. And mostly I get uncontrolled PHP errors and warnings like "trying to get property of non-object", instead of controlled and checked warnings.

So, what is the "correct" or recommended way to do this stuff?
The fact that I am manually doing two separate things here and manually doing the access check indicates that I might be missing something..
In core Drupal try-catch blocks are pretty rare, because code is consistent, and core (boldly) assumes that code in contrib and custom modules will be good, too. One core function simply won't send malformed data (like non-objects where object is expected) to another - and won't expect another code to send inconsistent data to it. So try-catch would only slow things down. On the database side, and on the user input side, checks are performed all right. This, of course, is by far most recommended approach. If you can make sure your data is coherent, do it. Don't call Entity API at all if you haven't ensure you will not cause EntityMalformedException.

The only place it's not possible is a border between Drupal and other systems (including database and http connection). There, you need to put safeguards up. Your points are correct then, but you need to add one more:


Call watchdog
Set message for admin
Tell your user that what he think he did might have not happened. For example, if your code failed to delete a photo user really, really need to have taken down and you won't tell him, he may be disappointed. In some situation, you may also find yourself in legal trouble.
And only now proceed