summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2022-12-29 14:53:47 +0100
committerLinus Groh <mail@linusgroh.de>2023-03-13 12:12:17 +0000
commit8f4d0d379706fa594b90d69edd8619cd1728c078 (patch)
tree8764bee590ebf341a714d11e33c3fd4b9b98e27c
parentdc318d30800e5b1741d5a1fdd3569321c1ad3603 (diff)
downloadserenity-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.cpp4
-rw-r--r--Userland/Libraries/LibCore/Promise.h10
-rw-r--r--Userland/Libraries/LibFileSystemAccessClient/Client.cpp10
-rw-r--r--Userland/Libraries/LibIMAP/Client.cpp13
-rw-r--r--Userland/Services/WebDriver/Session.cpp7
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;