diff --git a/gio/gappinfo.c b/gio/gappinfo.c index 5fbaff538..264de6913 100644 --- a/gio/gappinfo.c +++ b/gio/gappinfo.c @@ -721,8 +721,8 @@ g_app_info_launch_uris_async (GAppInfo *appinfo, task = g_task_new (appinfo, cancellable, callback, user_data); g_task_set_source_tag (task, g_app_info_launch_uris_async); - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Operation not supported for the current backend."); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Operation not supported for the current backend."); g_object_unref (task); return; diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c index a2154a25d..42134a601 100644 --- a/gio/gdbusconnection.c +++ b/gio/gdbusconnection.c @@ -1828,7 +1828,7 @@ send_message_data_deliver_error (GTask *task, send_message_with_reply_cleanup (task, TRUE); CONNECTION_UNLOCK (connection); - g_task_return_new_error (task, domain, code, "%s", message); + g_task_return_new_error_literal (task, domain, code, message); g_object_unref (task); } @@ -2386,10 +2386,10 @@ cancel_method_on_close (gpointer key, gpointer value, gpointer user_data) if (data->delivered) return FALSE; - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CLOSED, - _("The connection is closed")); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CLOSED, + _("The connection is closed")); /* Ask send_message_with_reply_cleanup not to remove the element from the * hash table - we're in the middle of a foreach; that would be unsafe. diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c index c69e9c66f..28083e4ed 100644 --- a/gio/gdbusprivate.c +++ b/gio/gdbusprivate.c @@ -1030,10 +1030,12 @@ write_message_continue_writing (MessageToWriteData *data) if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)) { GTask *task = g_steal_pointer (&data->task); - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Tried sending a file descriptor but remote peer does not support this capability"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Tried sending a file descriptor " + "but remote peer does not support " + "this capability"); g_clear_object (&task); goto out; } diff --git a/gio/gfile.c b/gio/gfile.c index 4527f9721..2ceeb3b05 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -7721,9 +7721,9 @@ query_default_handler_query_app_info_for_type_cb (GObject *object, } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { - g_task_return_new_error (task, - G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "%s", error->message); + g_task_return_new_error_literal (task, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + error->message); } else { @@ -7774,10 +7774,10 @@ query_default_handler_query_info_cb (GObject *object, } else { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_NOT_SUPPORTED, - _("No application is registered as handling this file")); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("No application is registered as handling this file")); } g_object_unref (info); diff --git a/gio/gnetworkmonitorbase.c b/gio/gnetworkmonitorbase.c index 4654d22e3..78e263444 100644 --- a/gio/gnetworkmonitorbase.c +++ b/gio/gnetworkmonitorbase.c @@ -285,8 +285,9 @@ can_reach_async_got_address (GObject *object, else { /* Resolved all addresses, none matched */ - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, - _("Host unreachable")); + g_task_return_new_error_literal (task, G_IO_ERROR, + G_IO_ERROR_HOST_UNREACHABLE, + _("Host unreachable")); g_object_unref (task); return; } @@ -321,8 +322,8 @@ g_network_monitor_base_can_reach_async (GNetworkMonitor *monitor, if (g_hash_table_size (G_NETWORK_MONITOR_BASE (monitor)->priv->networks) == 0) { - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE, - _("Network unreachable")); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE, + _("Network unreachable")); g_object_unref (task); return; } diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c index bc51178b1..f48d3e6f0 100644 --- a/gio/gnetworkmonitorportal.c +++ b/gio/gnetworkmonitorportal.c @@ -561,9 +561,9 @@ can_reach_done (GObject *source, if (reachable) g_task_return_boolean (task, TRUE); else - g_task_return_new_error (task, - G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, - "Can't reach host"); + g_task_return_new_error_literal (task, + G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + "Can't reach host"); g_object_unref (task); } diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c index c0f44a9de..083d27132 100644 --- a/gio/gopenuriportal.c +++ b/gio/gopenuriportal.c @@ -182,11 +182,11 @@ response_received (GDBusConnection *connection, g_task_return_boolean (task, TRUE); break; case XDG_DESKTOP_PORTAL_CANCELLED: - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled"); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled"); break; case XDG_DESKTOP_PORTAL_FAILED: default: - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed"); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed"); break; } diff --git a/gio/goutputstream.c b/gio/goutputstream.c index e3d1ac34c..1348208dd 100644 --- a/gio/goutputstream.c +++ b/gio/goutputstream.c @@ -1764,9 +1764,9 @@ g_output_stream_splice_async (GOutputStream *stream, if (g_input_stream_is_closed (source)) { - g_task_return_new_error (task, - G_IO_ERROR, G_IO_ERROR_CLOSED, - _("Source stream is already closed")); + g_task_return_new_error_literal (task, + G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Source stream is already closed")); g_object_unref (task); return; } diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c index 68b78ef13..0d1539a9d 100644 --- a/gio/gproxyaddressenumerator.c +++ b/gio/gproxyaddressenumerator.c @@ -343,9 +343,14 @@ complete_async (GTask *task) priv->last_error = NULL; } else if (!priv->ever_enumerated) - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, _("Unspecified proxy lookup failure")); + { + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unspecified proxy lookup failure")); + } else - g_task_return_pointer (task, NULL, NULL); + { + g_task_return_pointer (task, NULL, NULL); + } priv->ever_enumerated = TRUE; diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c index 6f256727a..71ac107da 100644 --- a/gio/gsocks5proxy.c +++ b/gio/gsocks5proxy.c @@ -724,10 +724,10 @@ nego_reply_read_cb (GObject *source, if (read == 0) { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CONNECTION_CLOSED, - "Connection to SOCKSv5 proxy server lost"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); g_object_unref (task); return; } @@ -837,10 +837,10 @@ auth_reply_read_cb (GObject *source, if (read == 0) { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CONNECTION_CLOSED, - "Connection to SOCKSv5 proxy server lost"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); g_object_unref (task); return; } @@ -949,10 +949,10 @@ connect_reply_read_cb (GObject *source, if (read == 0) { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CONNECTION_CLOSED, - "Connection to SOCKSv5 proxy server lost"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); g_object_unref (task); return; } @@ -1019,10 +1019,10 @@ connect_addr_len_read_cb (GObject *source, if (read == 0) { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CONNECTION_CLOSED, - "Connection to SOCKSv5 proxy server lost"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); g_object_unref (task); return; } @@ -1055,10 +1055,10 @@ connect_addr_read_cb (GObject *source, if (read == 0) { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_CONNECTION_CLOSED, - "Connection to SOCKSv5 proxy server lost"); + g_task_return_new_error_literal (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); g_object_unref (task); return; } diff --git a/gio/gtask.c b/gio/gtask.c index 60c2ab989..dd5730bd5 100644 --- a/gio/gtask.c +++ b/gio/gtask.c @@ -2031,7 +2031,8 @@ g_task_propagate_boolean (GTask *task, * Call g_error_copy() on the error if you need to keep a local copy * as well. * - * See also g_task_return_new_error(). + * See also [method@Gio.Task.return_new_error], + * [method@Gio.Task.return_new_error_literal]. * * Since: 2.36 */ @@ -2130,6 +2131,32 @@ g_task_return_new_error (GTask *task, g_task_return_error (task, error); } +/** + * g_task_return_new_error_literal: + * @task: a #GTask. + * @domain: a #GQuark. + * @code: an error code. + * @message: an error message + * + * Sets @task’s result to a new [type@GLib.Error] created from @domain, @code, + * @message and completes the task. + * + * See [method@Gio.Task.return_pointer] for more discussion of exactly what + * ‘completing the task’ means. + * + * See also [method@Gio.Task.return_new_error]. + * + * Since: 2.80 + */ +void +g_task_return_new_error_literal (GTask *task, + GQuark domain, + gint code, + const char *message) +{ + g_task_return_error (task, g_error_new_literal (domain, code, message)); +} + /** * g_task_return_error_if_cancelled: * @task: a #GTask diff --git a/gio/gtask.h b/gio/gtask.h index 3c2c97490..9fabddce1 100644 --- a/gio/gtask.h +++ b/gio/gtask.h @@ -175,6 +175,12 @@ void g_task_return_new_error (GTask *task, gint code, const char *format, ...) G_GNUC_PRINTF (4, 5); + +GIO_AVAILABLE_IN_2_80 +void g_task_return_new_error_literal (GTask *task, + GQuark domain, + gint code, + const char *message); GIO_AVAILABLE_IN_2_64 void g_task_return_value (GTask *task, GValue *result); diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c index 58336c0c1..f75c93404 100644 --- a/gio/gthreadedresolver.c +++ b/gio/gthreadedresolver.c @@ -1448,8 +1448,10 @@ timeout_cb (gpointer user_data) g_mutex_unlock (&data->lock); if (should_return) - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, - _("Socket I/O timed out")); + { + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Socket I/O timed out")); + } /* Signal completion of the task. */ g_mutex_lock (&data->lock); diff --git a/gio/gunixmount.c b/gio/gunixmount.c index 7055d8edd..ec6c57353 100644 --- a/gio/gunixmount.c +++ b/gio/gunixmount.c @@ -262,7 +262,7 @@ eject_unmount_done (GObject *source, { if (!g_subprocess_get_successful (subprocess)) /* ...but bad exit code */ - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_FAILED, stderr_str); else /* ...and successful exit code */ g_task_return_boolean (task, TRUE); diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c index a0f00ffbb..67374570b 100644 --- a/gio/gunixvolume.c +++ b/gio/gunixvolume.c @@ -287,7 +287,7 @@ eject_mount_done (GObject *source, { if (!g_subprocess_get_successful (subprocess)) /* ...but bad exit code */ - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str); + g_task_return_new_error_literal (task, G_IO_ERROR, G_IO_ERROR_FAILED, stderr_str); else { /* ...and successful exit code */ diff --git a/gio/tests/proxy-test.c b/gio/tests/proxy-test.c index e040c63b6..ca3f4b3d4 100644 --- a/gio/tests/proxy-test.c +++ b/gio/tests/proxy-test.c @@ -797,9 +797,9 @@ g_fake_resolver_lookup_by_name_async (GResolver *resolver, } else { - g_task_return_new_error (task, - G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, - "Not found"); + g_task_return_new_error_literal (task, + G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + "Not found"); } g_object_unref (task); } diff --git a/gio/tests/task.c b/gio/tests/task.c index c164a0631..a7f23125c 100644 --- a/gio/tests/task.c +++ b/gio/tests/task.c @@ -129,12 +129,19 @@ test_basic (void) /* test_error */ +typedef struct { + GQuark expected_domain; + int expected_code; + char *expected_message; + gssize int_result; +} TaskErrorResult; + static void error_callback (GObject *object, GAsyncResult *result, gpointer user_data) { - gssize *result_out = user_data; + TaskErrorResult *result_inout = user_data; GError *error = NULL; g_assert (object == NULL); @@ -143,13 +150,12 @@ error_callback (GObject *object, g_assert (g_task_had_error (G_TASK (result))); g_assert_false (g_task_get_completed (G_TASK (result))); - *result_out = g_task_propagate_int (G_TASK (result), &error); - g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + result_inout->int_result = g_task_propagate_int (G_TASK (result), &error); + g_assert_error (error, result_inout->expected_domain, result_inout->expected_code); + g_assert_cmpstr (error->message, ==, result_inout->expected_message); g_error_free (error); g_assert (g_task_had_error (G_TASK (result))); - - g_main_loop_quit (loop); } static gboolean @@ -159,7 +165,7 @@ error_return (gpointer user_data) g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed"); + "Failed %p", task); g_object_unref (task); return FALSE; @@ -177,15 +183,17 @@ static void test_error (void) { GTask *task; - gssize result; + TaskErrorResult result; gboolean first_task_data_destroyed = FALSE; gboolean second_task_data_destroyed = FALSE; - gboolean notification_emitted = FALSE; task = g_task_new (NULL, NULL, error_callback, &result); + result = (TaskErrorResult){ + .expected_domain = G_IO_ERROR, + .expected_code = G_IO_ERROR_FAILED, + .expected_message = g_strdup_printf ("Failed %p", task), + }; g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); - g_signal_connect (task, "notify::completed", - (GCallback) completed_cb, ¬ification_emitted); g_assert (first_task_data_destroyed == FALSE); g_task_set_task_data (task, &first_task_data_destroyed, error_destroy_notify); @@ -197,12 +205,59 @@ test_error (void) g_assert (second_task_data_destroyed == FALSE); g_idle_add (error_return, task); - g_main_loop_run (loop); + wait_for_completed_notification (task); - g_assert_cmpint (result, ==, -1); + g_assert_cmpint (result.int_result, ==, -1); g_assert (second_task_data_destroyed == TRUE); - g_assert_true (notification_emitted); g_assert (task == NULL); + g_free (result.expected_message); +} + +static void +test_error_literal (void) +{ + GTask *task; + TaskErrorResult result; + + task = g_task_new (NULL, NULL, error_callback, &result); + result = (TaskErrorResult){ + .expected_domain = G_IO_ERROR, + .expected_code = G_IO_ERROR_FAILED, + .expected_message = "Literal Failure", + }; + + g_task_return_new_error_literal (task, + result.expected_domain, + result.expected_code, + "Literal Failure"); + + wait_for_completed_notification (task); + g_assert_cmpint (result.int_result, ==, -1); + + g_assert_finalize_object (task); +} + +static void +test_error_literal_from_variable (void) +{ + GTask *task; + TaskErrorResult result; + + task = g_task_new (NULL, NULL, error_callback, &result); + result = (TaskErrorResult){ + .expected_domain = G_IO_ERROR, + .expected_code = G_IO_ERROR_FAILED, + .expected_message = "Literal Failure", + }; + + g_task_return_new_error_literal (task, + result.expected_domain, + result.expected_code, + result.expected_message); + + wait_for_completed_notification (task); + g_assert_cmpint (result.int_result, ==, -1); + g_assert_finalize_object (task); } /* test_return_from_same_iteration: calling g_task_return_* from the @@ -2524,6 +2579,8 @@ main (int argc, char **argv) g_test_add_func ("/gtask/basic", test_basic); g_test_add_func ("/gtask/error", test_error); + g_test_add_func ("/gtask/error-literal", test_error_literal); + g_test_add_func ("/gtask/error-literal-from-variable", test_error_literal_from_variable); g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration); g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel); g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread); diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c index c0c58b5c5..a64181e0a 100644 --- a/gio/tests/tls-interaction.c +++ b/gio/tests/tls-interaction.c @@ -149,7 +149,7 @@ test_interaction_ask_password_async_failure (GTlsInteraction *interaction, task = g_task_new (self, cancellable, callback, user_data); - g_task_return_new_error (task, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message"); + g_task_return_new_error_literal (task, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message"); g_object_unref (task); } @@ -348,7 +348,7 @@ test_interaction_request_certificate_async_failure (GTlsInteraction *interact task = g_task_new (self, cancellable, callback, user_data); - g_task_return_new_error (task, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message"); + g_task_return_new_error_literal (task, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message"); g_object_unref (task); }