fix: surface segment/entity read faults loudly instead of masking as absent
ColumnStore silently skipped a manifest-listed segment it could not load: a corrupt or missing segment dropped every one of its entities out of filter/rangeQuery/sortTopK with no error, so an inconsistent index read as a merely short result. It now throws a typed ColumnSegmentLoadError when a listed segment yields undecodable or no bytes, and lets a genuine storage IO fault propagate verbatim. Only a field with no manifest at all stays benign (nothing was ever written for it). baseStorage.getNoun_internal / getVerb_internal likewise caught every error and returned null, reporting a present-but-unreadable entity as "not found". They now return null only for genuine ENOENT-class absence (via isAbsentError) and rethrow real faults and deserialize errors. Pattern-B (blind catch) hardening: absence -> null, fault -> loud.
This commit is contained in:
parent
119087a75c
commit
af5d2f389b
3 changed files with 216 additions and 33 deletions
|
|
@ -29,6 +29,7 @@ import { getShardId } from './sharding.js'
|
|||
import { BlobStorage, type BlobStoreAdapter } from './blobStorage.js'
|
||||
import { unwrapBinaryData } from './binaryDataCodec.js'
|
||||
import { prodLog } from '../utils/logger.js'
|
||||
import { isAbsentError } from '../utils/errorClassification.js'
|
||||
import { BrainyError } from '../errors/brainyError.js'
|
||||
import { MetadataWriteBuffer } from '../utils/metadataWriteBuffer.js'
|
||||
import {
|
||||
|
|
@ -4064,8 +4065,12 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
return this.deserializeNoun(noun)
|
||||
}
|
||||
} catch (error) {
|
||||
// Entity not found
|
||||
return null
|
||||
// A real storage/deserialize fault is NOT "entity not found":
|
||||
// readCanonicalObject returns null for genuine absence and only throws on
|
||||
// a real fault, so masking it here reports a present-but-unreadable entity
|
||||
// as missing. Absence → null, fault → propagate loudly.
|
||||
if (isAbsentError(error)) return null
|
||||
throw error
|
||||
}
|
||||
|
||||
return null
|
||||
|
|
@ -4175,8 +4180,12 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
return this.deserializeVerb(verb)
|
||||
}
|
||||
} catch (error) {
|
||||
// Entity not found
|
||||
return null
|
||||
// A real storage/deserialize fault is NOT "relationship not found":
|
||||
// readCanonicalObject returns null for genuine absence and only throws on
|
||||
// a real fault, so masking it here reports a present-but-unreadable edge
|
||||
// as missing. Absence → null, fault → propagate loudly.
|
||||
if (isAbsentError(error)) return null
|
||||
throw error
|
||||
}
|
||||
|
||||
return null
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue