@@ -8,6 +8,7 @@ import type { QueryDORpc } from "./types.js";
88import { instantiateWasm , rowsToColumnArrays , type WasmEngine } from "./wasm-engine.js" ;
99import { resolveBucket } from "./bucket.js" ;
1010import { withTimeout } from "./coalesce.js" ;
11+ import { QueryModeError } from "./errors.js" ;
1112import wasmModule from "./wasm-module.js" ;
1213
1314const textEncoder = new TextEncoder ( ) ;
@@ -41,7 +42,7 @@ export class MasterDO extends DurableObject<Env> {
4142 async writeRpc ( body : unknown ) : Promise < unknown > {
4243 const { r2Key } = body as { r2Key : string } ;
4344 if ( ! r2Key || typeof r2Key !== "string" || r2Key . includes ( ".." ) ) {
44- throw new Error ( "Invalid r2Key" ) ;
45+ throw new QueryModeError ( "QUERY_FAILED" , "Invalid r2Key" ) ;
4546 }
4647
4748 // Check if this is a dataset directory (ends with / or .lance/)
@@ -50,7 +51,7 @@ export class MasterDO extends DurableObject<Env> {
5051 }
5152
5253 const result = await this . readFooterAndColumns ( r2Key ) ;
53- if ( ! result ) throw new Error ( " Failed to read footer" ) ;
54+ if ( ! result ) throw new QueryModeError ( "INVALID_FORMAT" , ` Failed to read footer for " ${ r2Key } "` ) ;
5455
5556 const tableName = r2Key . replace ( / \. ( l a n c e | p a r q u e t ) $ / , "" ) . split ( "/" ) . pop ( ) ?? r2Key ;
5657 const totalRows = result . columns [ 0 ] ?. pages . reduce ( ( s , p ) => s + p . rowCount , 0 ) ?? 0 ;
@@ -72,14 +73,14 @@ export class MasterDO extends DurableObject<Env> {
7273 const manifestKeys = listed . objects
7374 . filter ( o => o . key . endsWith ( ".manifest" ) )
7475 . sort ( ( a , b ) => { const na = parseInt ( a . key . split ( "/" ) . pop ( ) ! , 10 ) ; const nb = parseInt ( b . key . split ( "/" ) . pop ( ) ! , 10 ) ; return na - nb ; } ) ;
75- if ( manifestKeys . length === 0 ) throw new Error ( " No manifests found" ) ;
76+ if ( manifestKeys . length === 0 ) throw new QueryModeError ( "TABLE_NOT_FOUND" , ` No manifests found in " ${ r2Prefix } "` ) ;
7677
7778 const latestKey = manifestKeys [ manifestKeys . length - 1 ] . key ;
7879 const manifestObj = await resolveBucket ( this . env , latestKey ) . get ( latestKey ) ;
79- if ( ! manifestObj ) throw new Error ( " Failed to read manifest" ) ;
80+ if ( ! manifestObj ) throw new QueryModeError ( "TABLE_NOT_FOUND" , ` Failed to read manifest " ${ latestKey } "` ) ;
8081
8182 const manifest = parseManifest ( await manifestObj . arrayBuffer ( ) ) ;
82- if ( ! manifest ) throw new Error ( " Failed to parse manifest" ) ;
83+ if ( ! manifest ) throw new QueryModeError ( "INVALID_FORMAT" , ` Failed to parse manifest " ${ latestKey } "` ) ;
8384
8485 // Read first fragment's footer to broadcast (Query DOs will discover the rest)
8586 if ( manifest . fragments . length > 0 ) {
@@ -111,7 +112,7 @@ export class MasterDO extends DurableObject<Env> {
111112
112113 /** Core append logic. Supports partitioned writes via options.partitionBy. */
113114 private async executeAppend ( table : string , rows : Record < string , unknown > [ ] , options ?: AppendOptions ) : Promise < AppendResult > {
114- if ( ! rows ?. length ) throw new Error ( " No rows provided") ;
115+ if ( ! rows ?. length ) throw new QueryModeError ( "QUERY_FAILED" , " No rows provided for append ") ;
115116
116117 // Partition-aware ingest: split rows by partition value, write separate fragments
117118 if ( options ?. partitionBy ) {
@@ -245,7 +246,7 @@ export class MasterDO extends DurableObject<Env> {
245246 }
246247 }
247248
248- throw new Error ( " CAS failed after max retries" ) ;
249+ throw new QueryModeError ( "QUERY_FAILED" , ` CAS failed after ${ MAX_RETRIES } retries for table " ${ table } "` ) ;
249250 }
250251
251252 /** Build a simple binary manifest for the _versions/ directory. */
@@ -317,10 +318,10 @@ export class MasterDO extends DurableObject<Env> {
317318 async refreshRpc ( body : unknown ) : Promise < unknown > {
318319 const { r2Key } = body as { r2Key : string } ;
319320 if ( ! r2Key || typeof r2Key !== "string" || r2Key . includes ( ".." ) ) {
320- throw new Error ( "Invalid r2Key" ) ;
321+ throw new QueryModeError ( "QUERY_FAILED" , "Invalid r2Key" ) ;
321322 }
322323 const result = await this . readFooterAndColumns ( r2Key ) ;
323- if ( ! result ) throw new Error ( " Failed to read footer" ) ;
324+ if ( ! result ) throw new QueryModeError ( "INVALID_FORMAT" , ` Failed to read footer for " ${ r2Key } "` ) ;
324325
325326 const tableName = r2Key . replace ( / \. ( l a n c e | p a r q u e t ) $ / , "" ) . split ( "/" ) . pop ( ) ?? r2Key ;
326327 await this . broadcast ( tableName , r2Key , result ) ;
0 commit comments