summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorJan de Visser <jan@de-visser.net>2021-11-05 19:05:59 -0400
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-12-04 20:49:22 +0330
commit001949d77a3e78ccd54a28f075d5e67619ed79bd (patch)
treed5eb463226238b98c79f1369d12588e7853e1f71 /Userland/Services
parent108de5dea032664e9f8e2278096a5021efd81884 (diff)
downloadserenity-001949d77a3e78ccd54a28f075d5e67619ed79bd.zip
LibSQL: Improve error handling
The handling of filesystem level errors was basically non-existing or consisting of `VERIFY_NOT_REACHED` assertions. Addressed this by * Adding `open` methods to `Heap` and `Database` which return errors. * Changing the interface of methods of these classes and clients downstream to propagate these errors. The constructors of `Heap` and `Database` don't open the underlying filesystem file anymore. The SQL statement handlers return an `SQLErrorCode::InternalError` error code if an error comes back from the lower levels. Note that some of these errors are things like duplicate index entry errors that should be caught before the SQL layer attempts to actually update the database. Added tests to catch attempts to open weird or non-existent files as databases. Finally, in between me writing this patch and submitting the PR the AK::Result<Foo, Bar> template got deprecated in favour of ErrorOr<Foo>. This resulted in more busywork.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/SQLServer/DatabaseConnection.cpp9
1 files changed, 6 insertions, 3 deletions
diff --git a/Userland/Services/SQLServer/DatabaseConnection.cpp b/Userland/Services/SQLServer/DatabaseConnection.cpp
index 97c50a32d5..f02d2cd415 100644
--- a/Userland/Services/SQLServer/DatabaseConnection.cpp
+++ b/Userland/Services/SQLServer/DatabaseConnection.cpp
@@ -29,8 +29,7 @@ DatabaseConnection::DatabaseConnection(String database_name, int client_id)
, m_connection_id(s_next_connection_id++)
, m_client_id(client_id)
{
- LexicalPath path(database_name);
- if (path.title() != database_name) {
+ if (LexicalPath path(m_database_name); (path.title() != m_database_name) || (path.dirname() != ".")) {
auto client_connection = ClientConnection::client_connection_for(m_client_id);
client_connection->async_connection_error(m_connection_id, (int)SQL::SQLErrorCode::InvalidDatabaseName, m_database_name);
return;
@@ -40,8 +39,12 @@ DatabaseConnection::DatabaseConnection(String database_name, int client_id)
s_connections.set(m_connection_id, *this);
deferred_invoke([this]() {
m_database = SQL::Database::construct(String::formatted("/home/anon/sql/{}.db", m_database_name));
- m_accept_statements = true;
auto client_connection = ClientConnection::client_connection_for(m_client_id);
+ if (auto maybe_error = m_database->open(); maybe_error.is_error()) {
+ client_connection->async_connection_error(m_connection_id, (int)SQL::SQLErrorCode::InternalError, maybe_error.error().string_literal());
+ return;
+ }
+ m_accept_statements = true;
if (client_connection)
client_connection->async_connected(m_connection_id, m_database_name);
else