From 8f4d0d379706fa594b90d69edd8619cd1728c078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Thu, 29 Dec 2022 14:53:47 +0100 Subject: LibCore+Userland: Make Promise's on_resolve fallible This will be primarily necessary for BackgroundAction integration, but it already allows us to add proper error handling in LibIMAP :^) --- Userland/Applications/Browser/CookieJar.cpp | 4 ++-- Userland/Libraries/LibCore/Promise.h | 10 ++++++---- Userland/Libraries/LibFileSystemAccessClient/Client.cpp | 10 +++++----- Userland/Libraries/LibIMAP/Client.cpp | 13 +++++++------ Userland/Services/WebDriver/Session.cpp | 7 ++++--- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Userland/Applications/Browser/CookieJar.cpp b/Userland/Applications/Browser/CookieJar.cpp index cb07e08566..1ad59b6453 100644 --- a/Userland/Applications/Browser/CookieJar.cpp +++ b/Userland/Applications/Browser/CookieJar.cpp @@ -571,10 +571,10 @@ void CookieJar::select_all_cookies_from_database(OnSelectAllCookiesResult on_res on_result(cookie.release_value()); }, [&]() { - promise->resolve({}); + MUST(promise->resolve({})); }, [&](auto) { - promise->resolve({}); + MUST(promise->resolve({})); }); MUST(promise->await()); diff --git a/Userland/Libraries/LibCore/Promise.h b/Userland/Libraries/LibCore/Promise.h index 9517f22074..a996eb7d45 100644 --- a/Userland/Libraries/LibCore/Promise.h +++ b/Userland/Libraries/LibCore/Promise.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Kyle Pereira + * Copyright (c) 2022, kleines Filmröllchen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,14 +17,15 @@ class Promise : public Object { C_OBJECT(Promise); public: - Function on_resolved; + Function(Result&)> on_resolved; - void resolve(Result&& result) + ErrorOr resolve(Result&& result) { m_pending_or_error = move(result); if (on_resolved) - on_resolved(m_pending_or_error.value()); + return on_resolved(m_pending_or_error->value()); + return {}; } void cancel(Error error) @@ -56,7 +58,7 @@ public: RefPtr> new_promise = Promise::construct(); on_resolved = [new_promise, func](Result& result) { auto t = func(result); - new_promise->resolve(move(t)); + return new_promise->resolve(move(t)); }; return new_promise; } diff --git a/Userland/Libraries/LibFileSystemAccessClient/Client.cpp b/Userland/Libraries/LibFileSystemAccessClient/Client.cpp index ded74eef9d..e4c7f18567 100644 --- a/Userland/Libraries/LibFileSystemAccessClient/Client.cpp +++ b/Userland/Libraries/LibFileSystemAccessClient/Client.cpp @@ -124,19 +124,19 @@ void Client::handle_prompt_end(i32 request_id, i32 error, Optional co // to handle it as opening a new, named file. if (error != -1 && error != ENOENT) GUI::MessageBox::show_error(request_data.parent_window, DeprecatedString::formatted("Opening \"{}\" failed: {}", *chosen_file, strerror(error))); - request_data.promise->resolve(Error::from_errno(error)); + request_data.promise->resolve(Error::from_errno(error)).release_value_but_fixme_should_propagate_errors(); return; } if (Core::DeprecatedFile::is_device(ipc_file->fd())) { GUI::MessageBox::show_error(request_data.parent_window, DeprecatedString::formatted("Opening \"{}\" failed: Cannot open device files", *chosen_file)); - request_data.promise->resolve(Error::from_string_literal("Cannot open device files")); + request_data.promise->resolve(Error::from_string_literal("Cannot open device files")).release_value_but_fixme_should_propagate_errors(); return; } if (Core::DeprecatedFile::is_directory(ipc_file->fd())) { GUI::MessageBox::show_error(request_data.parent_window, DeprecatedString::formatted("Opening \"{}\" failed: Cannot open directory", *chosen_file)); - request_data.promise->resolve(Error::from_errno(EISDIR)); + request_data.promise->resolve(Error::from_errno(EISDIR)).release_value_but_fixme_should_propagate_errors(); return; } @@ -146,11 +146,11 @@ void Client::handle_prompt_end(i32 request_id, i32 error, Optional co return File({}, move(stream), filename); }(); if (file_or_error.is_error()) { - request_data.promise->resolve(file_or_error.release_error()); + request_data.promise->resolve(file_or_error.release_error()).release_value_but_fixme_should_propagate_errors(); return; } - request_data.promise->resolve(file_or_error.release_value()); + request_data.promise->resolve(file_or_error.release_value()).release_value_but_fixme_should_propagate_errors(); } void Client::die() diff --git a/Userland/Libraries/LibIMAP/Client.cpp b/Userland/Libraries/LibIMAP/Client.cpp index 22a89ccf25..894a4a0dc1 100644 --- a/Userland/Libraries/LibIMAP/Client.cpp +++ b/Userland/Libraries/LibIMAP/Client.cpp @@ -64,7 +64,7 @@ ErrorOr Client::on_ready_to_receive() // Once we get server hello we can start sending. if (m_connect_pending) { - m_connect_pending->resolve({}); + TRY(m_connect_pending->resolve({})); m_connect_pending.clear(); m_buffer.clear(); return {}; @@ -227,13 +227,13 @@ ErrorOr Client::handle_parsed_response(ParseStatus&& parse_status) bool should_send_next = false; if (!parse_status.successful) { m_expecting_response = false; - m_pending_promises.first()->resolve({}); + TRY(m_pending_promises.first()->resolve({})); m_pending_promises.remove(0); } if (parse_status.response.has_value()) { m_expecting_response = false; should_send_next = parse_status.response->has(); - m_pending_promises.first()->resolve(move(parse_status.response)); + TRY(m_pending_promises.first()->resolve(move(parse_status.response))); m_pending_promises.remove(0); } @@ -386,13 +386,14 @@ RefPtr>> Client::append(StringView mailbox, Mess auto response_promise = Promise>::construct(); m_pending_promises.append(response_promise); - continue_req->on_resolved = [this, message2 { move(message) }](auto& data) { + continue_req->on_resolved = [this, message2 { move(message) }](auto& data) -> ErrorOr { if (!data.has_value()) { - MUST(handle_parsed_response({ .successful = false, .response = {} })); + TRY(handle_parsed_response({ .successful = false, .response = {} })); } else { - MUST(send_raw(message2.data)); + TRY(send_raw(message2.data)); m_expecting_response = true; } + return {}; }; return cast_promise(response_promise); diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index d3427711bf..89db4b9791 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -42,7 +42,8 @@ ErrorOr> Session::create_server(NonnullRefPtron_accept = [this, promise](auto client_socket) { auto maybe_connection = adopt_nonnull_ref_or_enomem(new (nothrow) WebContentConnection(move(client_socket), m_client, session_id())); if (maybe_connection.is_error()) { - promise->resolve(maybe_connection.release_error()); + // Use of MUST in this function is safe, as our promise callback can never error out. + MUST(promise->resolve(maybe_connection.release_error())); return; } @@ -56,11 +57,11 @@ ErrorOr> Session::create_server(NonnullRefPtrresolve({}); + MUST(promise->resolve({})); }; server->on_accept_error = [promise](auto error) { - promise->resolve(move(error)); + MUST(promise->resolve(move(error))); }; return server; -- cgit v1.2.3