diff options
author | kleines Filmröllchen <filmroellchen@serenityos.org> | 2022-12-29 14:53:47 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-03-13 12:12:17 +0000 |
commit | 8f4d0d379706fa594b90d69edd8619cd1728c078 (patch) | |
tree | 8764bee590ebf341a714d11e33c3fd4b9b98e27c | |
parent | dc318d30800e5b1741d5a1fdd3569321c1ad3603 (diff) | |
download | serenity-8f4d0d379706fa594b90d69edd8619cd1728c078.zip |
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 :^)
-rw-r--r-- | Userland/Applications/Browser/CookieJar.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Promise.h | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibFileSystemAccessClient/Client.cpp | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Client.cpp | 13 | ||||
-rw-r--r-- | 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 <hey@xylepereira.me> + * Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,14 +17,15 @@ class Promise : public Object { C_OBJECT(Promise); public: - Function<void(Result&)> on_resolved; + Function<ErrorOr<void>(Result&)> on_resolved; - void resolve(Result&& result) + ErrorOr<void> 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<Promise<T>> new_promise = Promise<T>::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<IPC::File> 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<IPC::File> 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<void> 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<void> 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<SolidResponse>(); - 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<Promise<Optional<SolidResponse>>> Client::append(StringView mailbox, Mess auto response_promise = Promise<Optional<Response>>::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<void> { 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<SolidResponse>(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<NonnullRefPtr<Core::LocalServer>> Session::create_server(NonnullRefPtr<S server->on_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<NonnullRefPtr<Core::LocalServer>> Session::create_server(NonnullRefPtr<S if (m_current_window_handle.is_empty()) m_current_window_handle = handle_name; - promise->resolve({}); + MUST(promise->resolve({})); }; server->on_accept_error = [promise](auto error) { - promise->resolve(move(error)); + MUST(promise->resolve(move(error))); }; return server; |