From 7e78ec448b3683429f2cff76f1be3a0e365cd086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Fri, 17 Jan 2025 03:56:26 +0900 Subject: [PATCH] Clean up error code related classes --- bindings/java/rs_src/errors.rs | 94 +++++++++++++++---- .../github/tursodatabase/LimboErrorCode.java | 40 +++++++- .../core/{Codes.java => SqliteCode.java} | 5 +- .../tursodatabase/exceptions/ErrorCode.java | 13 --- .../utils/LimboExceptionUtils.java | 40 ++++++++ .../org/github/tursodatabase/JDBCTest.java | 1 + .../tursodatabase/core/LimboDBTest.java | 2 +- 7 files changed, 163 insertions(+), 32 deletions(-) rename bindings/java/src/main/java/org/github/tursodatabase/core/{Codes.java => SqliteCode.java} (98%) delete mode 100644 bindings/java/src/main/java/org/github/tursodatabase/exceptions/ErrorCode.java create mode 100644 bindings/java/src/main/java/org/github/tursodatabase/utils/LimboExceptionUtils.java diff --git a/bindings/java/rs_src/errors.rs b/bindings/java/rs_src/errors.rs index 7924ffb68..b11f46e3c 100644 --- a/bindings/java/rs_src/errors.rs +++ b/bindings/java/rs_src/errors.rs @@ -1,10 +1,49 @@ use jni::errors::{Error, JniError}; +use thiserror::Error; -#[derive(Debug, Clone)] -pub struct CustomError { - pub message: String, +#[derive(Debug, Error)] +pub enum LimboError { + #[error("Custom error: `{0}`")] + CustomError(String), + + #[error("Invalid database pointer")] + InvalidDatabasePointer, + + #[error("Invalid connection pointer")] + InvalidConnectionPointer, + + #[error("JNI Errors: `{0}`")] + JNIErrors(Error) } +impl From for LimboError { + fn from(value: limbo_core::LimboError) -> Self { + todo!() + } +} + +impl From for JniError { + fn from(value: LimboError) -> Self { + match value { + LimboError::CustomError(_) + | LimboError::InvalidDatabasePointer + | LimboError::InvalidConnectionPointer + | LimboError::JNIErrors(_) => { + eprintln!("Error occurred: {:?}", value); + JniError::Other(-1) + } + } + } +} + +impl From for LimboError { + fn from(value: jni::errors::Error) -> Self { + LimboError::JNIErrors(value) + } +} + +pub type Result = std::result::Result; + /// This struct defines error codes that correspond to the constants defined in the /// Java package `org.github.tursodatabase.LimboErrorCode`. /// @@ -18,17 +57,40 @@ impl ErrorCode { pub const STATEMENT_IS_DML: i32 = -1; } -impl From for CustomError { - fn from(value: Error) -> Self { - CustomError { - message: value.to_string(), - } - } -} +pub const SQLITE_OK: i32 = 0; +pub const SQLITE_ERROR: i32 = 1; +pub const SQLITE_INTERNAL: i32 = 2; +pub const SQLITE_PERM: i32 = 3; +pub const SQLITE_ABORT: i32 = 4; +pub const SQLITE_BUSY: i32 = 5; +pub const SQLITE_LOCKED: i32 = 6; +pub const SQLITE_NOMEM: i32 = 7; +pub const SQLITE_READONLY: i32 = 8; +pub const SQLITE_INTERRUPT: i32 = 9; +pub const SQLITE_IOERR: i32 = 10; +pub const SQLITE_CORRUPT: i32 = 11; +pub const SQLITE_NOTFOUND: i32 = 12; +pub const SQLITE_FULL: i32 = 13; +pub const SQLITE_CANTOPEN: i32 = 14; +pub const SQLITE_PROTOCOL: i32 = 15; +pub const SQLITE_EMPTY: i32 = 16; +pub const SQLITE_SCHEMA: i32 = 17; +pub const SQLITE_TOOBIG: i32 = 18; +pub const SQLITE_CONSTRAINT: i32 = 19; +pub const SQLITE_MISMATCH: i32 = 20; +pub const SQLITE_MISUSE: i32 = 21; +pub const SQLITE_NOLFS: i32 = 22; +pub const SQLITE_AUTH: i32 = 23; +pub const SQLITE_ROW: i32 = 100; +pub const SQLITE_DONE: i32 = 101; -impl From for JniError { - fn from(value: CustomError) -> Self { - eprintln!("Error occurred: {:?}", value.message); - JniError::Other(-1) - } -} +// types returned by sqlite3_column_type() +pub const SQLITE_INTEGER: i32 = 1; +pub const SQLITE_FLOAT: i32 = 2; +pub const SQLITE_TEXT: i32 = 3; +pub const SQLITE_BLOB: i32 = 4; +pub const SQLITE_NULL: i32 = 5; + +// Limbo custom error codes +pub const LIMBO_DATABASE_ALREADY_CLOSED: i32 = 1000; +pub const LIMBO_ETC: i32 = 9999; diff --git a/bindings/java/src/main/java/org/github/tursodatabase/LimboErrorCode.java b/bindings/java/src/main/java/org/github/tursodatabase/LimboErrorCode.java index 0c65ba04f..e3edd21a9 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/LimboErrorCode.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/LimboErrorCode.java @@ -1,8 +1,46 @@ package org.github.tursodatabase; +import org.github.tursodatabase.core.SqliteCode; + +/** + * Limbo error code. Superset of SQLite3 error code. + */ public enum LimboErrorCode { + SQLITE_OK(SqliteCode.SQLITE_OK, "Successful result"), + SQLITE_ERROR(SqliteCode.SQLITE_ERROR, "SQL error or missing database"), + SQLITE_INTERNAL(SqliteCode.SQLITE_INTERNAL, "An internal logic error in SQLite"), + SQLITE_PERM(SqliteCode.SQLITE_PERM, "Access permission denied"), + SQLITE_ABORT(SqliteCode.SQLITE_ABORT, "Callback routine requested an abort"), + SQLITE_BUSY(SqliteCode.SQLITE_BUSY, "The database file is locked"), + SQLITE_LOCKED(SqliteCode.SQLITE_LOCKED, "A table in the database is locked"), + SQLITE_NOMEM(SqliteCode.SQLITE_NOMEM, "A malloc() failed"), + SQLITE_READONLY(SqliteCode.SQLITE_READONLY, "Attempt to write a readonly database"), + SQLITE_INTERRUPT(SqliteCode.SQLITE_INTERRUPT, "Operation terminated by sqlite_interrupt()"), + SQLITE_IOERR(SqliteCode.SQLITE_IOERR, "Some kind of disk I/O error occurred"), + SQLITE_CORRUPT(SqliteCode.SQLITE_CORRUPT, "The database disk image is malformed"), + SQLITE_NOTFOUND(SqliteCode.SQLITE_NOTFOUND, "(Internal Only) Table or record not found"), + SQLITE_FULL(SqliteCode.SQLITE_FULL, "Insertion failed because database is full"), + SQLITE_CANTOPEN(SqliteCode.SQLITE_CANTOPEN, "Unable to open the database file"), + SQLITE_PROTOCOL(SqliteCode.SQLITE_PROTOCOL, "Database lock protocol error"), + SQLITE_EMPTY(SqliteCode.SQLITE_EMPTY, "(Internal Only) Database table is empty"), + SQLITE_SCHEMA(SqliteCode.SQLITE_SCHEMA, "The database schema changed"), + SQLITE_TOOBIG(SqliteCode.SQLITE_TOOBIG, "Too much data for one row of a table"), + SQLITE_CONSTRAINT(SqliteCode.SQLITE_CONSTRAINT, "Abort due to constraint violation"), + SQLITE_MISMATCH(SqliteCode.SQLITE_MISMATCH, "Data type mismatch"), + SQLITE_MISUSE(SqliteCode.SQLITE_MISUSE, "Library used incorrectly"), + SQLITE_NOLFS(SqliteCode.SQLITE_NOLFS, "Uses OS features not supported on host"), + SQLITE_AUTH(SqliteCode.SQLITE_AUTH, "Authorization denied"), + SQLITE_ROW(SqliteCode.SQLITE_ROW, "sqlite_step() has another row ready"), + SQLITE_DONE(SqliteCode.SQLITE_DONE, "sqlite_step() has finished executing"), + SQLITE_INTEGER(SqliteCode.SQLITE_INTEGER, "Integer type"), + SQLITE_FLOAT(SqliteCode.SQLITE_FLOAT, "Float type"), + SQLITE_TEXT(SqliteCode.SQLITE_TEXT, "Text type"), + SQLITE_BLOB(SqliteCode.SQLITE_BLOB, "Blob type"), + SQLITE_NULL(SqliteCode.SQLITE_NULL, "Null type"), + UNKNOWN_ERROR(-1, "Unknown error"), - ETC(9999, "Unclassified error"); + LIMBO_DATABASE_ALREADY_CLOSED(1000, "Database already closed"), + LIMBO_ETC(9999, "Unclassified error"); public final int code; public final String message; diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/Codes.java b/bindings/java/src/main/java/org/github/tursodatabase/core/SqliteCode.java similarity index 98% rename from bindings/java/src/main/java/org/github/tursodatabase/core/Codes.java rename to bindings/java/src/main/java/org/github/tursodatabase/core/SqliteCode.java index 0f8a3c402..3a879cb46 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/Codes.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/SqliteCode.java @@ -15,7 +15,10 @@ */ package org.github.tursodatabase.core; -public class Codes { +/** + * Sqlite error codes. + */ +public class SqliteCode { /** Successful result */ public static final int SQLITE_OK = 0; diff --git a/bindings/java/src/main/java/org/github/tursodatabase/exceptions/ErrorCode.java b/bindings/java/src/main/java/org/github/tursodatabase/exceptions/ErrorCode.java deleted file mode 100644 index 7dbed9812..000000000 --- a/bindings/java/src/main/java/org/github/tursodatabase/exceptions/ErrorCode.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.github.tursodatabase.exceptions; - - -/** - * This class defines error codes that correspond to specific error conditions - * that may occur while communicating with the JNI. - *

- * Refer to ErrorCode in rust package. - * TODO: Deprecate - */ -public class ErrorCode { - public static int CONNECTION_FAILURE = -1; -} diff --git a/bindings/java/src/main/java/org/github/tursodatabase/utils/LimboExceptionUtils.java b/bindings/java/src/main/java/org/github/tursodatabase/utils/LimboExceptionUtils.java new file mode 100644 index 000000000..9a45db040 --- /dev/null +++ b/bindings/java/src/main/java/org/github/tursodatabase/utils/LimboExceptionUtils.java @@ -0,0 +1,40 @@ +package org.github.tursodatabase.utils; + +import org.github.tursodatabase.LimboErrorCode; +import org.github.tursodatabase.annotations.Nullable; +import org.github.tursodatabase.exceptions.LimboException; + +import java.sql.SQLException; + +import static org.github.tursodatabase.utils.ByteArrayUtils.utf8ByteBufferToString; + +public class LimboExceptionUtils { + /** + * Throws formatted SQLException with error code and message. + * + * @param errorCode Error code. + * @param errorMessageBytes Error message. + */ + public static void throwLimboException(int errorCode, byte[] errorMessageBytes) throws SQLException { + String errorMessage = utf8ByteBufferToString(errorMessageBytes); + throw buildLimboException(errorCode, errorMessage); + } + + /** + * Throws formatted SQLException with error code and message. + * + * @param errorCode Error code. + * @param errorMessage Error message. + */ + public static LimboException buildLimboException(int errorCode, @Nullable String errorMessage) throws SQLException { + LimboErrorCode code = LimboErrorCode.getErrorCode(errorCode); + String msg; + if (code == LimboErrorCode.UNKNOWN_ERROR) { + msg = String.format("%s:%s (%s)", code, errorCode, errorMessage); + } else { + msg = String.format("%s (%s)", code, errorMessage); + } + + return new LimboException(msg, code); + } +} diff --git a/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java b/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java index 45452f810..7f28ddb5d 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/JDBCTest.java @@ -1,5 +1,6 @@ package org.github.tursodatabase; +import org.github.tursodatabase.core.LimboConnection; import org.junit.jupiter.api.Test; import java.sql.Connection; diff --git a/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java index 66e842ea4..9feb39fb7 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java @@ -36,7 +36,7 @@ public class LimboDBTest { LimboDB.load(); LimboDB db = LimboDB.create("jdbc:sqlite:" + dbPath, dbPath); - final int limboExceptionCode = LimboErrorCode.ETC.code; + final int limboExceptionCode = LimboErrorCode.LIMBO_ETC.code; try { db.throwJavaException(limboExceptionCode); } catch (Exception e) {