mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 18:47:41 +00:00
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 :^)
This commit is contained in:
parent
dc318d3080
commit
8f4d0d3797
5 changed files with 24 additions and 20 deletions
|
@ -571,10 +571,10 @@ void CookieJar::select_all_cookies_from_database(OnSelectAllCookiesResult on_res
|
||||||
on_result(cookie.release_value());
|
on_result(cookie.release_value());
|
||||||
},
|
},
|
||||||
[&]() {
|
[&]() {
|
||||||
promise->resolve({});
|
MUST(promise->resolve({}));
|
||||||
},
|
},
|
||||||
[&](auto) {
|
[&](auto) {
|
||||||
promise->resolve({});
|
MUST(promise->resolve({}));
|
||||||
});
|
});
|
||||||
|
|
||||||
MUST(promise->await());
|
MUST(promise->await());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Kyle Pereira <hey@xylepereira.me>
|
* Copyright (c) 2021, Kyle Pereira <hey@xylepereira.me>
|
||||||
|
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -16,14 +17,15 @@ class Promise : public Object {
|
||||||
C_OBJECT(Promise);
|
C_OBJECT(Promise);
|
||||||
|
|
||||||
public:
|
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);
|
m_pending_or_error = move(result);
|
||||||
|
|
||||||
if (on_resolved)
|
if (on_resolved)
|
||||||
on_resolved(m_pending_or_error.value());
|
return on_resolved(m_pending_or_error->value());
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void cancel(Error error)
|
void cancel(Error error)
|
||||||
|
@ -56,7 +58,7 @@ public:
|
||||||
RefPtr<Promise<T>> new_promise = Promise<T>::construct();
|
RefPtr<Promise<T>> new_promise = Promise<T>::construct();
|
||||||
on_resolved = [new_promise, func](Result& result) {
|
on_resolved = [new_promise, func](Result& result) {
|
||||||
auto t = func(result);
|
auto t = func(result);
|
||||||
new_promise->resolve(move(t));
|
return new_promise->resolve(move(t));
|
||||||
};
|
};
|
||||||
return new_promise;
|
return new_promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// to handle it as opening a new, named file.
|
||||||
if (error != -1 && error != ENOENT)
|
if (error != -1 && error != ENOENT)
|
||||||
GUI::MessageBox::show_error(request_data.parent_window, DeprecatedString::formatted("Opening \"{}\" failed: {}", *chosen_file, strerror(error)));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Core::DeprecatedFile::is_device(ipc_file->fd())) {
|
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));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Core::DeprecatedFile::is_directory(ipc_file->fd())) {
|
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));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,11 +146,11 @@ void Client::handle_prompt_end(i32 request_id, i32 error, Optional<IPC::File> co
|
||||||
return File({}, move(stream), filename);
|
return File({}, move(stream), filename);
|
||||||
}();
|
}();
|
||||||
if (file_or_error.is_error()) {
|
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;
|
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()
|
void Client::die()
|
||||||
|
|
|
@ -64,7 +64,7 @@ ErrorOr<void> Client::on_ready_to_receive()
|
||||||
|
|
||||||
// Once we get server hello we can start sending.
|
// Once we get server hello we can start sending.
|
||||||
if (m_connect_pending) {
|
if (m_connect_pending) {
|
||||||
m_connect_pending->resolve({});
|
TRY(m_connect_pending->resolve({}));
|
||||||
m_connect_pending.clear();
|
m_connect_pending.clear();
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
return {};
|
return {};
|
||||||
|
@ -227,13 +227,13 @@ ErrorOr<void> Client::handle_parsed_response(ParseStatus&& parse_status)
|
||||||
bool should_send_next = false;
|
bool should_send_next = false;
|
||||||
if (!parse_status.successful) {
|
if (!parse_status.successful) {
|
||||||
m_expecting_response = false;
|
m_expecting_response = false;
|
||||||
m_pending_promises.first()->resolve({});
|
TRY(m_pending_promises.first()->resolve({}));
|
||||||
m_pending_promises.remove(0);
|
m_pending_promises.remove(0);
|
||||||
}
|
}
|
||||||
if (parse_status.response.has_value()) {
|
if (parse_status.response.has_value()) {
|
||||||
m_expecting_response = false;
|
m_expecting_response = false;
|
||||||
should_send_next = parse_status.response->has<SolidResponse>();
|
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);
|
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();
|
auto response_promise = Promise<Optional<Response>>::construct();
|
||||||
m_pending_promises.append(response_promise);
|
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()) {
|
if (!data.has_value()) {
|
||||||
MUST(handle_parsed_response({ .successful = false, .response = {} }));
|
TRY(handle_parsed_response({ .successful = false, .response = {} }));
|
||||||
} else {
|
} else {
|
||||||
MUST(send_raw(message2.data));
|
TRY(send_raw(message2.data));
|
||||||
m_expecting_response = true;
|
m_expecting_response = true;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
return cast_promise<SolidResponse>(response_promise);
|
return cast_promise<SolidResponse>(response_promise);
|
||||||
|
|
|
@ -42,7 +42,8 @@ ErrorOr<NonnullRefPtr<Core::LocalServer>> Session::create_server(NonnullRefPtr<S
|
||||||
server->on_accept = [this, promise](auto client_socket) {
|
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()));
|
auto maybe_connection = adopt_nonnull_ref_or_enomem(new (nothrow) WebContentConnection(move(client_socket), m_client, session_id()));
|
||||||
if (maybe_connection.is_error()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,11 +57,11 @@ ErrorOr<NonnullRefPtr<Core::LocalServer>> Session::create_server(NonnullRefPtr<S
|
||||||
if (m_current_window_handle.is_empty())
|
if (m_current_window_handle.is_empty())
|
||||||
m_current_window_handle = handle_name;
|
m_current_window_handle = handle_name;
|
||||||
|
|
||||||
promise->resolve({});
|
MUST(promise->resolve({}));
|
||||||
};
|
};
|
||||||
|
|
||||||
server->on_accept_error = [promise](auto error) {
|
server->on_accept_error = [promise](auto error) {
|
||||||
promise->resolve(move(error));
|
MUST(promise->resolve(move(error)));
|
||||||
};
|
};
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue