Clean up error code related classes

This commit is contained in:
김선우 2025-01-17 03:56:26 +09:00
parent fcadc2f825
commit 7e78ec448b
7 changed files with 163 additions and 32 deletions

View file

@ -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<limbo_core::LimboError> for LimboError {
fn from(value: limbo_core::LimboError) -> Self {
todo!()
}
}
impl From<LimboError> 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<jni::errors::Error> for LimboError {
fn from(value: jni::errors::Error) -> Self {
LimboError::JNIErrors(value)
}
}
pub type Result<T> = std::result::Result<T, LimboError>;
/// 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<jni::errors::Error> 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<CustomError> 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;

View file

@ -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;

View file

@ -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;

View file

@ -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.
* <p />
* Refer to ErrorCode in rust package.
* TODO: Deprecate
*/
public class ErrorCode {
public static int CONNECTION_FAILURE = -1;
}

View file

@ -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);
}
}

View file

@ -1,5 +1,6 @@
package org.github.tursodatabase;
import org.github.tursodatabase.core.LimboConnection;
import org.junit.jupiter.api.Test;
import java.sql.Connection;

View file

@ -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) {