[geary/mjog/imap-connection-fixes: 1/4] Geary.Imap.Command: Add throw_on_error method
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/imap-connection-fixes: 1/4] Geary.Imap.Command: Add throw_on_error method
- Date: Sat, 28 Mar 2020 02:14:23 +0000 (UTC)
commit 3c15004871f8b54cd2bad88f1d441600d4fe1b99
Author: Michael Gratton <mike vee net>
Date: Thu Mar 26 22:20:45 2020 +1100
Geary.Imap.Command: Add throw_on_error method
Add method that checks the command's status response and throws an
appropriate error if it indicates that something we care about is
wrong.
src/engine/imap/command/imap-command.vala | 102 ++++++++++++++++++++++++
test/engine/imap/command/imap-command-test.vala | 88 ++++++++++++++++++++
test/meson.build | 1 +
test/test-engine.vala | 1 +
4 files changed, 192 insertions(+)
---
diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala
index 58163671..322b18d2 100644
--- a/src/engine/imap/command/imap-command.vala
+++ b/src/engine/imap/command/imap-command.vala
@@ -271,6 +271,108 @@ public abstract class Geary.Imap.Command : BaseObject {
}
}
+ /**
+ * Throws an error if this command's status response is NO or BAD.
+ *
+ * If the response is NO, an ImapError.OPERATIONAL_ERROR is
+ * thrown. If the response is BAD, an ImapError.SERVER_ERROR is
+ * thrown. If a specific response code is set, another more
+ * appropriate exception may be thrown. The given command is used
+ * to provide additional context information in case an error is
+ * thrown.
+ */
+ public void throw_on_error() throws ImapError {
+ StatusResponse? response = this.status;
+ if (response != null && response.status in new Status[] { BAD, NO }) {
+ ResponseCode? code = response.response_code;
+ if (code != null) {
+ ResponseCodeType code_type = code.get_response_code_type();
+ switch (code_type.value) {
+ case ResponseCodeType.ALREADYEXISTS:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Already exists: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.AUTHENTICATIONFAILED:
+ throw new ImapError.UNAUTHENTICATED(
+ "%s: Bad credentials: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.AUTHORIZATIONFAILED:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Not authorised: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.CANNOT:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Cannot be performed: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.LIMIT:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Hit limit: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.NOPERM:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Not permitted by ACL: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.NONEXISTENT:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Does not exist: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.OVERQUOTA:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Over quota: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case ResponseCodeType.UNAVAILABLE:
+ throw new ImapError.UNAVAILABLE(
+ "%s: Server is unavailable: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+ }
+ }
+
+ // No interesting response code, so just throw a generic
+ // error
+ switch (response.status) {
+ case Status.NO:
+ throw new ImapError.OPERATIONAL_ERROR(
+ "%s: Operational server error: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+
+ case Status.BAD:
+ throw new ImapError.SERVER_ERROR(
+ "%s: Fatal server error: %s",
+ to_brief_string(),
+ response.to_string()
+ );
+ }
+ }
+ }
+
public virtual string to_string() {
string args = this.args.to_string();
return (Geary.String.is_empty(args))
diff --git a/test/engine/imap/command/imap-command-test.vala b/test/engine/imap/command/imap-command-test.vala
new file mode 100644
index 00000000..68705b1c
--- /dev/null
+++ b/test/engine/imap/command/imap-command-test.vala
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2020 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+class Geary.Imap.CommandTest : TestCase {
+
+
+ private class TestCommand : Command {
+
+ public TestCommand() {
+ base("TEST");
+ }
+
+ }
+
+
+ public CommandTest() {
+ base("Geary.Imap.CommandTest");
+ add_test("throw_on_error", throw_on_error);
+ }
+
+ public void throw_on_error() throws GLib.Error {
+ var test_article = newCompleteTestCommand(OK, null);
+ test_article.throw_on_error();
+
+ test_article = newCompleteTestCommand(NO, null);
+ try {
+ test_article.throw_on_error();
+ assert_not_reached();
+ } catch (ImapError.OPERATIONAL_ERROR err) {
+ // expected
+ }
+
+ test_article = newCompleteTestCommand(BAD, null);
+ try {
+ test_article.throw_on_error();
+ assert_not_reached();
+ } catch (ImapError.SERVER_ERROR err) {
+ // expected
+ }
+
+ test_article = newCompleteTestCommand(
+ NO, ResponseCodeType.AUTHENTICATIONFAILED
+ );
+ try {
+ test_article.throw_on_error();
+ assert_not_reached();
+ } catch (ImapError.UNAUTHENTICATED err) {
+ // expected
+ }
+
+ test_article = newCompleteTestCommand(
+ NO, ResponseCodeType.UNAVAILABLE
+ );
+ try {
+ test_article.throw_on_error();
+ assert_not_reached();
+ } catch (ImapError.UNAVAILABLE err) {
+ // expected
+ }
+ }
+
+ private Command newCompleteTestCommand(Status status,
+ string? response_code)
+ throws GLib.Error {
+ var command = new TestCommand();
+ command.assign_tag(new Tag("t001"));
+
+ ResponseCode? code = null;
+ if (response_code != null) {
+ code = new ResponseCode();
+ code.add(new AtomParameter(response_code));
+ }
+
+ try {
+ command.completed(new StatusResponse(command.tag, status, code));
+ } catch (ImapError.SERVER_ERROR err) {
+ if (status != BAD) {
+ throw err;
+ }
+ }
+ return command;
+ }
+
+}
diff --git a/test/meson.build b/test/meson.build
index 9cd4717f..86d7782d 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -36,6 +36,7 @@ geary_test_engine_sources = [
'engine/common/common-contact-harvester-test.vala',
'engine/db/db-database-test.vala',
'engine/db/db-versioned-database-test.vala',
+ 'engine/imap/command/imap-command-test.vala',
'engine/imap/command/imap-create-command-test.vala',
'engine/imap/command/imap-fetch-command-test.vala',
'engine/imap/message/imap-data-format-test.vala',
diff --git a/test/test-engine.vala b/test/test-engine.vala
index a70cb11c..1826609f 100644
--- a/test/test-engine.vala
+++ b/test/test-engine.vala
@@ -50,6 +50,7 @@ int main(string[] args) {
// Other IMAP tests rely on these working, so test them first
engine.add_suite(new Geary.Imap.DataFormatTest().get_suite());
+ engine.add_suite(new Geary.Imap.CommandTest().get_suite());
engine.add_suite(new Geary.Imap.CreateCommandTest().get_suite());
engine.add_suite(new Geary.Imap.FetchCommandTest().get_suite());
engine.add_suite(new Geary.Imap.ListParameterTest().get_suite());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]