improved handling of authentication/connection failed errors

This commit is contained in:
leithoff 2016-06-09 15:46:51 +02:00
parent 0e83ef74b9
commit caafb0b84b
2 changed files with 280 additions and 231 deletions

View File

@ -202,9 +202,10 @@ class Mail
if (is_null($_reuseCache)) $_reuseCache = $_restoreSession;
//error_log(__METHOD__.' ('.__LINE__.') '.' RestoreSession:'.$_restoreSession.' ProfileId:'.$_profileID.'/'.Mail\Account::get_default_acc_id().' for user:'.$GLOBALS['egw_info']['user']['account_lid'].' called from:'.function_backtrace());
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_oldImapServerObject));
if (isset(self::$profileDefunct[$_profileID]) && self::$profileDefunct[$_profileID]===true)
self::$profileDefunct = Cache::getCache(Cache::INSTANCE,'email','profileDefunct'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),5*1);
if (isset(self::$profileDefunct[$_profileID]) && strlen(self::$profileDefunct[$_profileID]))
{
throw new Exception(__METHOD__." failed to instanciate Mail for $_profileID / ".$this->profileID." with error:".$e->getMessage().($e->details?', '.$e->details:''));
throw new Exception(__METHOD__." failed to instanciate Mail for Profile #$_profileID Reason:".self::$profileDefunct[$_profileID]);
}
if ($_oldImapServerObject instanceof Mail\Imap)
{
@ -909,7 +910,7 @@ class Mail
{
static $quota;
if (isset($quota)) return $quota;
if (isset(self::$profileDefunct[$this->profileID]) && self::$profileDefunct[$this->profileID]===true)
if (isset(self::$profileDefunct[$this->profileID]) && strlen(self::$profileDefunct[$this->profileID]))
{
// something is wrong. Do not proceed. either no folder or profile is marked as defunct for this request
return false;
@ -929,7 +930,8 @@ class Mail
//error_log(__METHOD__." failed to fetch quota on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:'')/*.function_backtrace()*/);
if ($e->getCode()==102)
{
self::$profileDefunct[$this->profileID]=true;
self::$profileDefunct[$this->profileID]=$e->getMessage().($e->details?', '.$e->details:'');
Cache::setCache(Cache::INSTANCE,'email','profileDefunct'.trim($GLOBALS['egw_info']['user']['account_id']),self::$profileDefunct, $expiration=5*1);
throw new Exception(__METHOD__." failed to fetch quota on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:''));
}
}
@ -1047,7 +1049,11 @@ class Mail
}
catch(\Exception $e)
{
if ($e->getCode()==102) self::$profileDefunct[$this->profileID]=true;
if ($e->getCode()==102)
{
self::$profileDefunct[$this->profileID]=$e->getMessage().($e->details?', '.$e->details:'');
Cache::setCache(Cache::INSTANCE,'email','profileDefunct'.trim($GLOBALS['egw_info']['user']['account_id']),self::$profileDefunct, $expiration=5*1);
}
unset($e);
$HierarchyDelimiter[$this->icServer->ImapServerId] = '/';
}
@ -1153,7 +1159,7 @@ class Mail
function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false,$fetchSubscribedInfo=true)
{
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '." called with:$_folderName,$ignoreStatusCache,$basicInfoOnly");
if (!is_string($_folderName) || empty($_folderName)||(isset(self::$profileDefunct[$this->profileID]) && self::$profileDefunct[$this->profileID]===true))
if (!is_string($_folderName) || empty($_folderName)||(isset(self::$profileDefunct[$this->profileID]) && strlen(self::$profileDefunct[$this->profileID])))
{
// something is wrong. Do not proceed. either no folder or profile is marked as defunct for this request
return false;
@ -1185,7 +1191,8 @@ class Mail
{
//error_log(__METHOD__.array2string($e));
//error_log(__METHOD__." failed to fetch Mailbox $_folderName on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:'')/*.function_backtrace()*/);
self::$profileDefunct[$this->profileID]=true;
self::$profileDefunct[$this->profileID]=$e->getMessage().($e->details?', '.$e->details:'');
Cache::setCache(Cache::INSTANCE,'email','profileDefunct'.trim($GLOBALS['egw_info']['user']['account_id']),self::$profileDefunct, $expiration=5*1);
throw new Exception(__METHOD__." failed to fetch Mailbox $_folderName on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:''));
}
//error_log(__METHOD__.' ('.__LINE__.') '.$_folderName.' '.array2string($ret));
@ -1210,7 +1217,8 @@ class Mail
{
//error_log(__METHOD__.array2string($e));
error_log(__METHOD__." failed to fetch status for $_folderName on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:'')/*.function_backtrace()*/);
self::$profileDefunct[$this->profileID]=true;
self::$profileDefunct[$this->profileID]=$e->getMessage().($e->details?', '.$e->details:'');
Cache::setCache(Cache::INSTANCE,'email','profileDefunct'.trim($GLOBALS['egw_info']['user']['account_id']),self::$profileDefunct, $expiration=5*1);
//throw new Exception(__METHOD__." failed to fetch status for $_folderName on ".$this->profileID.' Reason:'.$e->getMessage().($e->details?', '.$e->details:''));
$folderInfo=null;
}
@ -3704,7 +3712,7 @@ class Mail
catch (\Exception $e)
{
error_log(__METHOD__.__LINE__.$e->getMessage().($e->details?', '.$e->details:''));
self::$profileDefunct[$this->profileID]=true;
self::$profileDefunct[$this->profileID]=$e->getMessage().($e->details?', '.$e->details:'');
$folderInfo[$this->profileID][$_folder] = false;
}
//error_log(__METHOD__.' ('.__LINE__.') '.' Folder Exists:'.$folderInfo[$this->profileID][$_folder].function_backtrace());

View File

@ -160,8 +160,14 @@ class mail_ui
}
catch (Exception $e)
{
// redirect to mail wizard to handle it (redirect works for ajax too)
self::callWizard($e->getMessage(),true,'error');
// we need this to handle failed JSONRequests
if (Api\Json\Request::isJSONRequest() && $_GET['menuaction'] != 'mail.mail_ui.index')
{
$response = Api\Json\Response::get();
$response->call('egw.message',$e->getMessage(),'error');
}
// redirect to mail wizard to handle it (redirect works for ajax too), unless index is called. we want the sidebox
if ($_GET['menuaction'] != 'mail.mail_ui.index') self::callWizard($e->getMessage(),true,'error',false);
}
if (Mail::$debugTimes) Mail::logRunTimes($starttime,null,'',__METHOD__.__LINE__);
}
@ -173,7 +179,7 @@ class mail_ui
* @param boolean $exit If true, will call exit() after opening the wizardpopup
* @param string $msg_type = 'success' message type
*/
static function callWizard($message, $exit=true, $msg_type='success')
static function callWizard($message, $exit=true, $msg_type='success',$reset_sidebox_on_index=true)
{
//error_log(__METHOD__."('$message', $exit) ".function_backtrace());
$linkData=(self::$icServerID ? array(
@ -192,7 +198,7 @@ class mail_ui
$windowName = "editMailAccount".self::$icServerID;
$response->call("egw.open_link", Egw::link('/index.php', $linkData), $windowName, "600x480",null,true);
Framework::message($message, 'error');
if ($_GET['menuaction'] == 'mail.mail_ui.index')
if ($_GET['menuaction'] == 'mail.mail_ui.index' && $reset_sidebox_on_index)
{
$response->call('framework.setSidebox','mail',array(),'md5');
}
@ -203,7 +209,8 @@ class mail_ui
}
else // regular GET request eg. in idots template
{
Framework::popup(Framework::link('/index.php',$linkData));
$windowName = "editMailAccount".self::$icServerID;
Framework::popup(Framework::link('/index.php',$linkData),$windowName);
$GLOBALS['egw']->framework->render($message,'',true);
if ($exit)
{
@ -449,17 +456,7 @@ class mail_ui
// These must always be set, even if $content is an array
$content[self::$nm_index]['cat_is_select'] = true; // Category select is just a normal selectbox
$content[self::$nm_index]['no_filter2'] = false; // Disable second filter
try
{
$content[self::$nm_index]['actions'] = self::get_actions();
}
catch (Exception $e)
{
// do not exit here. mail-tree should be build. if we exit here, we never get there
self::callWizard($e->getMessage().($e->details?', '.$e->details:''),false, 'error');
unset($e);
//return false;
}
$content[self::$nm_index]['row_id'] = 'row_id'; // is a concatenation of trim($GLOBALS['egw_info']['user']['account_id']):profileID:base64_encode(FOLDERNAME):uid
$content[self::$nm_index]['placeholder_actions'] = array('composeasnew');
$content[self::$nm_index]['get_rows'] = 'mail_ui::get_rows';
@ -555,6 +552,54 @@ class mail_ui
$etpl = new Etemplate('mail.index');
//apply infolog_filter_change javascript method (hide/show of date filter form) over onchange filter
$content[self::$nm_index]['cat_id_onchange'] = "app.mail.mail_searchtype_change()";
// set the actions on tree
$etpl->setElementAttribute(self::$nm_index.'[foldertree]','actions', $this->get_tree_actions());
// sending preview toolbar actions
if ($content['mailSplitter']) $etpl->setElementAttribute('mailPreview[toolbar]', 'actions', $this->get_toolbar_actions());
// We need to send toolbar actions to client-side because view template needs them
if (Api\Header\UserAgent::mobile()) $sel_options['toolbar'] = $this->get_toolbar_actions();
//we use the category "filter" option as specifier where we want to search (quick, subject, from, to, etc. ....)
if (empty($content[self::$nm_index]['cat_id']) || empty($content[self::$nm_index]['search']))
{
$content[self::$nm_index]['cat_id']=($content[self::$nm_index]['cat_id']?(!Mail::$supportsORinQuery[$this->mail_bo->profileID]&&($content[self::$nm_index]['cat_id']=='quick'||$content[self::$nm_index]['cat_id']=='quickwithcc')?'subject':$content[self::$nm_index]['cat_id']):(Mail::$supportsORinQuery[$this->mail_bo->profileID]?'quick':'subject'));
}
$readonlys = $preserv = array();
if (Mail::$debugTimes) Mail::logRunTimes($starttime,null,'',__METHOD__.__LINE__);
}
catch (Exception $e)
{
// do not exit here. mail-tree should be build. if we exit here, we never get there.
error_log(__METHOD__.__LINE__.$e->getMessage().($e->details?', '.$e->details:'').' Menuaction:'.$_GET['menuaction'].'.'.function_backtrace());
if (empty($etpl))
{
$sel_options[self::$nm_index]['foldertree'] = $this->mail_tree->getInitialIndexTree(null, $this->mail_bo->profileID, null, !$this->mail_bo->mailPreferences['showAllFoldersInFolderPane'],!$this->mail_bo->mailPreferences['showAllFoldersInFolderPane']);
$etpl = new Etemplate('mail.index');
}
$etpl->setElementAttribute(self::$nm_index.'[foldertree]','actions', $this->get_tree_actions(false));
$readonlys = $preserv = array();
if (empty($content)) $content=array();
self::callWizard($e->getMessage().$e->getMessage().($e->details?', '.$e->details:''),false, 'error',false);
//return false;
}
// Check preview pane is enabled, then show spliter
if ($this->mail_bo->mailPreferences['previewPane']) $etpl->setElementAttribute('mail.index.spliter', 'template', 'mail.index.nospliter');
return $etpl->exec('mail.mail_ui.index',$content,$sel_options,$readonlys,$preserv);
}
/**
* Get tree actions / context menu for tree
*
* Changes here, may require to log out, as $content[self::$nm_index] get stored in session!
* @param {boolean} $imap_actions set to false if you want to avoid to talk to the imap-server
* @return array
*/
function get_tree_actions($imap_actions=true)
{
// Start at 2 so auto-added copy+paste actions show up as second group
// Needed because there's no 'select all' action to push things down
$group=1;
@ -704,8 +749,8 @@ class mail_ui
);
break;
}
$junkFolder = ($imap_actions?$this->mail_bo->getJunkFolder():null);
$junkFolder = $this->mail_bo->getJunkFolder();
//error_log(__METHOD__.__LINE__.$junkFolder);
if ($junkFolder && !empty($junkFolder))
{
@ -743,34 +788,7 @@ class mail_ui
// manage folders should not affect the ability to subscribe or unsubscribe
// to existing folders, it should only affect add/rename/move/delete
}
$etpl->setElementAttribute(self::$nm_index.'[foldertree]','actions', $tree_actions);
// sending preview toolbar actions
if ($content['mailSplitter']) $etpl->setElementAttribute('mailPreview[toolbar]', 'actions', $this->get_toolbar_actions());
// We need to send toolbar actions to client-side because view template needs them
if (Api\Header\UserAgent::mobile()) $sel_options['toolbar'] = $this->get_toolbar_actions();
//we use the category "filter" option as specifier where we want to search (quick, subject, from, to, etc. ....)
if (empty($content[self::$nm_index]['cat_id']) || empty($content[self::$nm_index]['search']))
{
$content[self::$nm_index]['cat_id']=($content[self::$nm_index]['cat_id']?(!Mail::$supportsORinQuery[$this->mail_bo->profileID]&&($content[self::$nm_index]['cat_id']=='quick'||$content[self::$nm_index]['cat_id']=='quickwithcc')?'subject':$content[self::$nm_index]['cat_id']):(Mail::$supportsORinQuery[$this->mail_bo->profileID]?'quick':'subject'));
}
$readonlys = $preserv = array();
if (Mail::$debugTimes) Mail::logRunTimes($starttime,null,'',__METHOD__.__LINE__);
}
catch (Exception $e)
{
// do not exit here. mail-tree should be build. if we exit here, we never get there
error_log(__METHOD__.__LINE__.$e->getMessage().($e->details?', '.$e->details:''));
self::callWizard(__METHOD__.$e->getMessage().$e->getMessage().($e->details?', '.$e->details:''),false, 'error');
//return false;
}
// Check preview pane is enabled, then show spliter
if ($this->mail_bo->mailPreferences['previewPane']) $etpl->setElementAttribute('mail.index.spliter', 'template', 'mail.index.nospliter');
return $etpl->exec('mail.mail_ui.index',$content,$sel_options,$readonlys,$preserv);
return $tree_actions;
}
/**
@ -1305,6 +1323,7 @@ class mail_ui
}
catch(Exception $e)
{
unset($e);
$rows=array();
return 0;
}
@ -1312,8 +1331,17 @@ class mail_ui
}
}
if (!isset($mail_ui))
{
try
{
$mail_ui = new mail_ui(true); // run constructor for current profile
}
catch(Exception $e)
{
unset($e);
$rows=array();
return 0;
}
if (empty($query['selectedFolder'])) $query['selectedFolder'] = $mail_ui->mail_bo->profileID.self::$delimiter.'INBOX';
}
//error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Start:'.$query['start'].' NumRows:'.$query['num_rows'].array2string($query['order']).'->'.array2string($query['sort']));
@ -4176,6 +4204,8 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$vacation = $cachedVacations[$icServerID];
if (!$vacation)
{
try
{
// Create mail app object
$mail = new mail_ui();
@ -4184,6 +4214,11 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
if ($icServerID != $mail->Mail->profileID) return;
$vacation = $mail->gatherVacation($cachedVacations);
} catch (Exception $e) {
$vacation=false;
error_log(__METHOD__.__LINE__." ".$e->getMessage());
unset($e);
}
}
if($vacation) {
@ -4262,13 +4297,13 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
Api\Translation::add_app('mail');
if (is_null($icServerID)) $icServerID = $this->mail_bo->profileID;
$rememberServerID = $this->mail_bo->profileID;
try
{
if ($icServerID && $icServerID != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this->changeProfile($icServerID);
}
try
{
$quota = $this->mail_bo->getQuotaRoot();
} catch (Exception $e) {
$quota['limit'] = 'NOT SET';
@ -4288,9 +4323,15 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$content['quotanotsupported'] = $sel_options[self::$nm_index]['quotanotsupported'] = "mail_DisplayNone";
}
if ($rememberServerID != $this->mail_bo->profileID)
{
try
{
//error_log(__METHOD__.__LINE__.' change Profile back to where we came from ->'.$rememberServerID);
$this->changeProfile($rememberServerID);
} catch (Exception $e) {
//error_log(__METHOD__.__LINE__." ".$e->getMessage());
unset($e);
}
}
$response = Api\Json\Response::get();
$response->call('app.mail.mail_setQuotaDisplay',array('data'=>$content));