How should a module change the value of the global
$user, execute its own code, and restore the original value of
$user without causing the current user to be logged out if an error happens?
The drupal_cron_run() function gives a perfect example for exactly this, since it changes the current user to anonymous whenever cron is run, then switches back after it is done.
// Prevent session information from being saved while doing funky stuff. $original_session_state = drupal_save_session(); drupal_save_session(FALSE); // Force the current user to anonymous to ensure consistent permissions on // funky stuff runs. $original_user = $GLOBALS['user']; $GLOBALS['user'] = drupal_anonymous_user(); // Or use user_load() for a non-anonymous user. // Do funky stuff here... // Restore the user. $GLOBALS['user'] = $original_user; drupal_save_session($original_session_state);