[libgdata] [core] Improve error reporting when there's no network connection
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] [core] Improve error reporting when there's no network connection
- Date: Mon, 29 Mar 2010 18:21:29 +0000 (UTC)
commit ba286a7f4b52f9c35d2062a9cc5c7181cc6573c9
Author: Philip Withnall <philip tecnocode co uk>
Date: Mon Mar 29 19:19:45 2010 +0100
[core] Improve error reporting when there's no network connection
Add GDATA_SERVICE_ERROR_NETWORK_ERROR and GDATA_SERVICE_ERROR_PROXY_ERROR,
to be returned by all network operations (authentication, queries,
insertions, updates and deletions) in case of a local network error or a
proxy error, respectively.
gdata/gdata-service.c | 37 ++++++++++++++++++++++++++++---------
gdata/gdata-service.h | 12 +++++++++---
gdata/tests/general.c | 33 +++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 12 deletions(-)
---
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index 8f2091e..84ad337 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -362,29 +362,42 @@ real_parse_error_response (GDataService *self, GDataOperationType operation_type
{
/* See: http://code.google.com/apis/gdata/docs/2.0/reference.html#HTTPStatusCodes */
switch (status) {
- case 400:
+ case SOUP_STATUS_CANT_RESOLVE:
+ case SOUP_STATUS_CANT_CONNECT:
+ case SOUP_STATUS_SSL_FAILED:
+ case SOUP_STATUS_IO_ERROR:
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NETWORK_ERROR,
+ _("Cannot connect to the service's server."));
+ return;
+ case SOUP_STATUS_CANT_RESOLVE_PROXY:
+ case SOUP_STATUS_CANT_CONNECT_PROXY:
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROXY_ERROR,
+ _("Cannot connect to the proxy server."));
+ return;
+ case SOUP_STATUS_MALFORMED:
+ case SOUP_STATUS_BAD_REQUEST: /* 400 */
g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
/* Translators: the parameter is an error message returned by the server. */
_("Invalid request URI or header, or unsupported nonstandard parameter: %s"), response_body);
return;
- case 401:
- case 403:
+ case SOUP_STATUS_UNAUTHORIZED: /* 401 */
+ case SOUP_STATUS_FORBIDDEN: /* 403 */
g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
/* Translators: the parameter is an error message returned by the server. */
_("Authentication required: %s"), response_body);
return;
- case 404:
+ case SOUP_STATUS_NOT_FOUND: /* 404 */
g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NOT_FOUND,
/* Translators: the parameter is an error message returned by the server. */
_("The requested resource was not found: %s"), response_body);
return;
- case 409:
- case 412:
+ case SOUP_STATUS_CONFLICT: /* 409 */
+ case SOUP_STATUS_PRECONDITION_FAILED: /* 412 */
g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_CONFLICT,
/* Translators: the parameter is an error message returned by the server. */
_("The entry has been modified since it was downloaded: %s"), response_body);
return;
- case 500:
+ case SOUP_STATUS_INTERNAL_SERVER_ERROR: /* 500 */
default:
/* We'll fall back to generic errors, below */
break;
@@ -392,6 +405,11 @@ real_parse_error_response (GDataService *self, GDataOperationType operation_type
/* If the error hasn't been handled already, throw a generic error */
switch (operation_type) {
+ case GDATA_OPERATION_AUTHENTICATION:
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+ /* Translators: the first parameter is an HTTP status, and the second is an error message returned by the server. */
+ _("Error code %u when authenticating: %s"), status, response_body);
+ break;
case GDATA_OPERATION_QUERY:
g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
/* Translators: the first parameter is an HTTP status, and the second is an error message returned by the server. */
@@ -776,8 +794,9 @@ login_error:
return retval;
protocol_error:
- g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
- _("The server returned a malformed response."));
+ g_assert (klass->parse_error_response != NULL);
+ klass->parse_error_response (self, GDATA_OPERATION_AUTHENTICATION, status, message->reason_phrase, message->response_body->data,
+ message->response_body->length, error);
general_error:
g_object_unref (message);
diff --git a/gdata/gdata-service.h b/gdata/gdata-service.h
index 35d15f6..a2ac3c5 100644
--- a/gdata/gdata-service.h
+++ b/gdata/gdata-service.h
@@ -36,6 +36,7 @@ G_BEGIN_DECLS
* @GDATA_OPERATION_DELETION: a deletion of a #GDataEntry
* @GDATA_OPERATION_DOWNLOAD: a download of a file
* @GDATA_OPERATION_UPLOAD: an upload of a file
+ * @GDATA_OPERATION_AUTHENTICATION: authentication with the service
*
* Representations of the different operations performed by the library.
*
@@ -47,12 +48,13 @@ typedef enum {
GDATA_OPERATION_UPDATE,
GDATA_OPERATION_DELETION,
GDATA_OPERATION_DOWNLOAD,
- GDATA_OPERATION_UPLOAD
+ GDATA_OPERATION_UPLOAD,
+ GDATA_OPERATION_AUTHENTICATION
} GDataOperationType;
/**
* GDataServiceError:
- * @GDATA_SERVICE_ERROR_UNAVAILABLE: The service is unavailable due to maintainence or other reasons
+ * @GDATA_SERVICE_ERROR_UNAVAILABLE: The service is unavailable due to maintainence or other reasons (e.g. network errors at the server end)
* @GDATA_SERVICE_ERROR_PROTOCOL_ERROR: The client or server unexpectedly strayed from the protocol (fatal error)
* @GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED: An entry has already been inserted, and cannot be re-inserted
* @GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED: The user attempted to do something which required authentication, and they weren't authenticated
@@ -61,6 +63,8 @@ typedef enum {
* and uploading the modified entry
* @GDATA_SERVICE_ERROR_FORBIDDEN: Generic error for a forbidden action (not due to having insufficient permissions)
* @GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER: A given query parameter was invalid for the query type
+ * @GDATA_SERVICE_ERROR_NETWORK_ERROR: The service is unavailable due to local network errors (e.g. no Internet connection)
+ * @GDATA_SERVICE_ERROR_PROXY_ERROR: The service is unavailable due to proxy network errors (e.g. proxy unreachable)
*
* Error codes for #GDataService operations.
**/
@@ -72,7 +76,9 @@ typedef enum {
GDATA_SERVICE_ERROR_NOT_FOUND,
GDATA_SERVICE_ERROR_CONFLICT,
GDATA_SERVICE_ERROR_FORBIDDEN,
- GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER
+ GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER,
+ GDATA_SERVICE_ERROR_NETWORK_ERROR,
+ GDATA_SERVICE_ERROR_PROXY_ERROR
} GDataServiceError;
/**
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index 78c1856..a96ce21 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -647,6 +647,33 @@ test_query_etag (void)
}
static void
+test_service_network_error (void)
+{
+ GDataService *service;
+ SoupURI *proxy_uri;
+ GError *error = NULL;
+
+ /* This is a little hacky, but it should work */
+ service = g_object_new (GDATA_TYPE_SERVICE, "client-id", CLIENT_ID, NULL);
+
+ /* Try a query which should always fail due to errors resolving the hostname */
+ g_assert (gdata_service_query (service, "http://thisshouldnotexist.localhost", NULL, GDATA_TYPE_ENTRY, NULL, NULL, NULL, &error) == NULL);
+ g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NETWORK_ERROR);
+ g_clear_error (&error);
+
+ /* Try one with a bad proxy set */
+ proxy_uri = soup_uri_new ("http://thisshouldalsonotexist.localhost/proxy");
+ gdata_service_set_proxy_uri (service, proxy_uri);
+ soup_uri_free (proxy_uri);
+
+ g_assert (gdata_service_query (service, "http://google.com", NULL, GDATA_TYPE_ENTRY, NULL, NULL, NULL, &error) == NULL);
+ g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROXY_ERROR);
+ g_clear_error (&error);
+
+ g_object_unref (service);
+}
+
+static void
test_access_rule_get_xml (void)
{
GDataAccessRule *rule, *rule2;
@@ -2760,16 +2787,22 @@ main (int argc, char *argv[])
{
gdata_test_init (&argc, &argv);
+ g_test_add_func ("/service/network_error", test_service_network_error);
+
g_test_add_func ("/entry/get_xml", test_entry_get_xml);
g_test_add_func ("/entry/parse_xml", test_entry_parse_xml);
g_test_add_func ("/entry/error_handling", test_entry_error_handling);
+
g_test_add_func ("/feed/parse_xml", test_feed_parse_xml);
g_test_add_func ("/feed/error_handling", test_feed_error_handling);
+
g_test_add_func ("/query/categories", test_query_categories);
g_test_add_func ("/query/unicode", test_query_unicode);
g_test_add_func ("/query/etag", test_query_etag);
+
g_test_add_func ("/access-rule/get_xml", test_access_rule_get_xml);
g_test_add_func ("/access-rule/error_handling", test_access_rule_error_handling);
+
g_test_add_func ("/color/parsing", test_color_parsing);
g_test_add_func ("/color/output", test_color_output);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]