Improving handling when opening folders that do not exist on remote.

Force close the folder if when opening a remote session indicates it
does not exist.

Also actually handle the folder not opening during a background sync.
This commit is contained in:
Michael Gratton 2018-09-26 23:24:17 +10:00
parent 4989cc78ef
commit c39b1e5457
2 changed files with 64 additions and 37 deletions

View file

@ -100,40 +100,58 @@ private class Geary.ImapEngine.RefreshFolderSync : FolderOperation {
base(account, folder);
}
public override async void execute(Cancellable cancellable)
throws Error {
bool opened = false;
bool closed = false;
public override async void execute(GLib.Cancellable cancellable)
throws GLib.Error {
bool was_opened = false;
try {
yield this.folder.open_async(Folder.OpenFlags.NONE, cancellable);
opened = true;
yield this.folder.wait_for_remote_async(cancellable);
debug("Synchronising : %s", this.folder.to_string());
was_opened = true;
debug("Synchronising %s", this.folder.to_string());
yield sync_folder(cancellable);
} finally {
if (opened) {
try {
// don't pass in the Cancellable; really need this
// to complete in all cases
closed = yield this.folder.close_async();
if (closed) {
// If the folder was actually closing, wait
// for it here to completely close so that its
// session has a chance to exit IMAP Selected
// state when released, allowing the next sync
// op to reuse the same session. Here we
// definitely want to use the cancellable so
// the wait can be interrupted.
yield this.folder.wait_for_close_async(cancellable);
}
} catch (Error err) {
debug(
"%s: Error closing folder %s: %s",
this.account.to_string(),
this.folder.to_string(),
err.message
);
} catch (GLib.IOError.CANCELLED err) {
// All good
} catch (EngineError.ALREADY_CLOSED err) {
// Failed to open the folder, which could be because the
// network went away, or because the remote folder went
// away. Either way don't bother reporting it.
debug(
"Folder failed to open %s: %s",
this.folder.to_string(),
err.message
);
} catch (GLib.Error err) {
this.account.report_problem(
new ServiceProblemReport(
ProblemType.GENERIC_ERROR,
this.account.information,
this.account.information.imap,
err
)
);
}
if (was_opened) {
try {
// don't pass in the Cancellable; really need this
// to complete in all cases
if (yield this.folder.close_async(null)) {
// If the folder was actually closing, wait
// for it here to completely close so that its
// session has a chance to exit IMAP Selected
// state when released, allowing the next sync
// op to reuse the same session. Here we
// definitely want to use the cancellable so
// the wait can be interrupted.
yield this.folder.wait_for_close_async(cancellable);
}
} catch (Error err) {
debug(
"%s: Error closing folder %s: %s",
this.account.to_string(),
this.folder.to_string(),
err.message
);
}
}
}

View file

@ -954,15 +954,24 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
Imap.FolderSession? session = null;
try {
session = yield this._account.claim_folder_session(this.path, cancellable);
session = yield this._account.claim_folder_session(
this.path, cancellable
);
} catch (IOError.CANCELLED err) {
// Fine, just bail out
return;
} catch (EngineError.NOT_FOUND err) {
// Folder no longer exists, so force closed
yield force_close(
CloseReason.LOCAL_CLOSE, CloseReason.REMOTE_ERROR
);
return;
} catch (Error err) {
if (!(err is IOError.CANCELLED)) {
// Notify that there was a connection error, but don't
// force the folder closed, since it might come good again
// if the user fixes an auth problem or the network comes
// back or whatever.
notify_open_failed(Folder.OpenFailed.REMOTE_ERROR, err);
}
// Notify that there was a connection error, but don't
// force the folder closed, since it might come good again
// if the user fixes an auth problem or the network comes
// back or whatever.
notify_open_failed(Folder.OpenFailed.REMOTE_ERROR, err);
return;
}