Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion package/cpp/NitroSQLiteException.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <exception>
#include <iostream>
#include <string>
#include <optional>

const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]";

enum NitroSQLiteExceptionType {
UnknownError,
Expand Down Expand Up @@ -33,7 +36,7 @@ class NitroSQLiteException : public std::exception {
explicit NitroSQLiteException(const std::string& message) : NitroSQLiteException(NitroSQLiteExceptionType::UnknownError, message) {}
NitroSQLiteException(const NitroSQLiteExceptionType& type, const char* message) : NitroSQLiteException(type, std::string(message)) {}
NitroSQLiteException(const NitroSQLiteExceptionType& type, const std::string& message)
: _exceptionString("[" + typeToString(type) + "] " + message) {}
: _exceptionString(NITRO_SQLITE_EXCEPTION_PREFIX + "[" + typeToString(type) + "] " + message) {}

private:
const std::string _exceptionString;
Expand Down
45 changes: 45 additions & 0 deletions package/src/NitroSQLiteError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const NITRO_SQLITE_ERROR_NAME = 'NitroSQLiteError' as const

/**
* Custom error class for NitroSQLite operations
* Extends the native Error class with proper prototype chain and error handling
*/
export default class NitroSQLiteError extends Error {
constructor(message: string, options?: ErrorOptions) {
super(message, options)
this.name = NITRO_SQLITE_ERROR_NAME

// Maintains proper prototype chain for instanceof checks
Object.setPrototypeOf(this, NitroSQLiteError.prototype)
}

/**
* Converts an unknown error to a NitroSQLiteError
* Preserves stack traces and error causes when available
*/
static fromError(error: unknown): NitroSQLiteError {
if (error instanceof NitroSQLiteError) {
return error
}

if (error instanceof Error) {
const nitroSQLiteError = new NitroSQLiteError(error.message, {
cause: error.cause,
})

// Preserve original stack trace if available
if (error.stack) {
nitroSQLiteError.stack = error.stack
}
return nitroSQLiteError
}

if (typeof error === 'string') {
return new NitroSQLiteError(error)
}

return new NitroSQLiteError('Unknown error occurred', {
cause: error,
})
}
}
36 changes: 22 additions & 14 deletions package/src/operations/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
SQLiteQueryParams,
QueryResultRow,
} from '../types'
import NitroSQLiteError from '../NitroSQLiteError'

export function execute<Row extends QueryResultRow = never>(
dbName: string,
Expand All @@ -18,13 +19,17 @@ export function execute<Row extends QueryResultRow = never>(
? toNativeQueryParams(params)
: (params as NativeSQLiteQueryParams)

const nativeResult = HybridNitroSQLite.execute(
dbName,
query,
transformedParams,
)
const result = buildJsQueryResult<Row>(nativeResult)
return result
try {
const nativeResult = HybridNitroSQLite.execute(
dbName,
query,
transformedParams,
)

return buildJsQueryResult<Row>(nativeResult)
} catch (error) {
throw NitroSQLiteError.fromError(error)
}
}

export async function executeAsync<Row extends QueryResultRow = never>(
Expand All @@ -36,13 +41,16 @@ export async function executeAsync<Row extends QueryResultRow = never>(
? toNativeQueryParams(params)
: (params as NativeSQLiteQueryParams)

const nativeResult = await HybridNitroSQLite.executeAsync(
dbName,
query,
transformedParams,
)
const result = buildJsQueryResult<Row>(nativeResult)
return result
try {
const nativeResult = await HybridNitroSQLite.executeAsync(
dbName,
query,
transformedParams,
)
return buildJsQueryResult<Row>(nativeResult)
} catch (error) {
throw NitroSQLiteError.fromError(error)
}
}

function toNativeQueryParams(
Expand Down
21 changes: 14 additions & 7 deletions package/src/operations/executeBatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
BatchQueryCommand,
NativeBatchQueryCommand,
} from '../types'
import NitroSQLiteError from '../NitroSQLiteError'

export function executeBatch(
dbName: string,
Expand All @@ -18,8 +19,11 @@ export function executeBatch(
? toNativeBatchQueryCommands(commands)
: (commands as NativeBatchQueryCommand[])

const result = HybridNitroSQLite.executeBatch(dbName, transformedCommands)
return result
try {
return HybridNitroSQLite.executeBatch(dbName, transformedCommands)
} catch (error) {
throw NitroSQLiteError.fromError(error)
}
}

export async function executeBatchAsync(
Expand All @@ -30,11 +34,14 @@ export async function executeBatchAsync(
? toNativeBatchQueryCommands(commands)
: (commands as NativeBatchQueryCommand[])

const result = await HybridNitroSQLite.executeBatchAsync(
dbName,
transformedCommands,
)
return result
try {
return await HybridNitroSQLite.executeBatchAsync(
dbName,
transformedCommands,
)
} catch (error) {
throw NitroSQLiteError.fromError(error)
}
}

function toNativeBatchQueryCommands(
Expand Down
34 changes: 18 additions & 16 deletions package/src/operations/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,30 @@ import type {
} from '../types'
import { execute, executeAsync } from './execute'
import { executeBatch, executeBatchAsync } from './executeBatch'
import NitroSQLiteError from '../NitroSQLiteError'

export function open(
options: NitroSQLiteConnectionOptions,
): NitroSQLiteConnection {
openDb(options.name, options.location)
try {
HybridNitroSQLite.open(options.name, options.location)
locks[options.name] = {
queue: [],
inProgress: false,
}
} catch (error) {
throw NitroSQLiteError.fromError(error)
}

return {
close: () => close(options.name),
close: () => {
try {
HybridNitroSQLite.close(options.name)
delete locks[options.name]
} catch (error) {
throw NitroSQLiteError.fromError(error)
}
},
delete: () => HybridNitroSQLite.drop(options.name, options.location),
attach: (dbNameToAttach: string, alias: string, location?: string) =>
HybridNitroSQLite.attach(options.name, dbNameToAttach, alias, location),
Expand All @@ -43,17 +59,3 @@ export function open(
HybridNitroSQLite.loadFileAsync(options.name, location),
}
}

export function openDb(dbName: string, location?: string) {
HybridNitroSQLite.open(dbName, location)

locks[dbName] = {
queue: [],
inProgress: false,
}
}

export function close(dbName: string) {
HybridNitroSQLite.close(dbName)
delete locks[dbName]
}
31 changes: 19 additions & 12 deletions package/src/operations/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { locks, HybridNitroSQLite } from '../nitro'
import NitroSQLiteError from '../NitroSQLiteError'
import type {
QueryResult,
Transaction,
Expand All @@ -25,7 +26,7 @@ export const transaction = (
fn: (tx: Transaction) => Promise<void> | void,
): Promise<void> => {
if (locks[dbName] == null)
throw Error(`Nitro SQLite Error: No lock found on db: ${dbName}`)
throw new NitroSQLiteError(`No lock found on db: ${dbName}`)

let isFinalized = false

Expand All @@ -35,8 +36,8 @@ export const transaction = (
params?: SQLiteQueryParams,
): QueryResult<Data> => {
if (isFinalized) {
throw Error(
`Nitro SQLite Error: Cannot execute query on finalized transaction: ${dbName}`,
throw new NitroSQLiteError(
`Cannot execute query on finalized transaction: ${dbName}`,
)
}
return execute(dbName, query, params)
Expand All @@ -47,17 +48,17 @@ export const transaction = (
params?: SQLiteQueryParams,
): Promise<QueryResult<Data>> => {
if (isFinalized) {
throw Error(
`Nitro SQLite Error: Cannot execute query on finalized transaction: ${dbName}`,
throw new NitroSQLiteError(
`Cannot execute query on finalized transaction: ${dbName}`,
)
}
return executeAsync(dbName, query, params)
}

const commit = () => {
if (isFinalized) {
throw Error(
`Nitro SQLite Error: Cannot execute commit on finalized transaction: ${dbName}`,
throw new NitroSQLiteError(
`Cannot execute commit on finalized transaction: ${dbName}`,
)
}
const result = HybridNitroSQLite.execute(dbName, 'COMMIT')
Expand All @@ -67,8 +68,8 @@ export const transaction = (

const rollback = () => {
if (isFinalized) {
throw Error(
`Nitro SQLite Error: Cannot execute rollback on finalized transaction: ${dbName}`,
throw new NitroSQLiteError(
`Cannot execute rollback on finalized transaction: ${dbName}`,
)
}
const result = HybridNitroSQLite.execute(dbName, 'ROLLBACK')
Expand Down Expand Up @@ -107,8 +108,13 @@ export const transaction = (

return new Promise((resolve, reject) => {
const tx: PendingTransaction = {
start: () => {
run().then(resolve).catch(reject)
start: async () => {
try {
const result = await run()
resolve(result)
} catch (error) {
reject(NitroSQLiteError.fromError(error))
}
},
}

Expand All @@ -118,7 +124,8 @@ export const transaction = (
}

function startNextTransaction(dbName: string) {
if (locks[dbName] == null) throw Error(`Lock not found for db: ${dbName}`)
if (locks[dbName] == null)
throw new NitroSQLiteError(`Lock not found for db: ${dbName}`)

if (locks[dbName].inProgress) {
// Transaction is already in process bail out
Expand Down
Loading