Skip to content

Commit 43d4e6d

Browse files
authored
Merge pull request #236 from effigies/throw-issues
rf: Throw more issue-like objects in loading functions
2 parents e60bdc9 + d5f9f98 commit 43d4e6d

File tree

9 files changed

+40
-32
lines changed

9 files changed

+40
-32
lines changed

src/files/json.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Deno.test('Test JSON error conditions', async (t) => {
4040
await loadJSON(BOMfile).catch((e) => {
4141
error = e
4242
})
43-
assertObjectMatch(error, { key: 'INVALID_JSON_ENCODING' })
43+
assertObjectMatch(error, { code: 'INVALID_JSON_ENCODING' })
4444
})
4545

4646
await t.step('Error on UTF-16', async () => {
@@ -49,7 +49,7 @@ Deno.test('Test JSON error conditions', async (t) => {
4949
await loadJSON(UTF16file).catch((e) => {
5050
error = e
5151
})
52-
assertObjectMatch(error, { key: 'INVALID_JSON_ENCODING' })
52+
assertObjectMatch(error, { code: 'INVALID_JSON_ENCODING' })
5353
})
5454

5555
await t.step('Error on invalid JSON syntax', async () => {
@@ -58,6 +58,6 @@ Deno.test('Test JSON error conditions', async (t) => {
5858
await loadJSON(badJSON).catch((e) => {
5959
error = e
6060
})
61-
assertObjectMatch(error, { key: 'JSON_INVALID' })
61+
assertObjectMatch(error, { code: 'JSON_INVALID' })
6262
})
6363
})

src/files/json.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function readJSONText(file: BIDSFile): Promise<string> {
1414
}
1515
return text
1616
} catch (error) {
17-
throw { key: 'INVALID_JSON_ENCODING' }
17+
throw { code: 'INVALID_JSON_ENCODING' }
1818
} finally {
1919
decoder.decode() // Reset decoder
2020
}
@@ -26,12 +26,12 @@ export async function loadJSON(file: BIDSFile): Promise<Record<string, unknown>>
2626
try {
2727
parsedText = JSON.parse(text)
2828
} catch (error) {
29-
throw { key: 'JSON_INVALID' } // Raise syntax errors
29+
throw { code: 'JSON_INVALID' } // Raise syntax errors
3030
}
3131
if (Array.isArray(parsedText) || typeof parsedText !== 'object') {
3232
throw {
33-
key: 'JSON_NOT_AN_OBJECT',
34-
evidence: text.substring(0, 10) + (text.length > 10 ? '...' : ''),
33+
code: 'JSON_NOT_AN_OBJECT',
34+
issueMessage: text.substring(0, 10) + (text.length > 10 ? '...' : ''),
3535
}
3636
}
3737
return parsedText

src/files/nifti.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Deno.test('Test loading nifti header', async (t) => {
5151
const header = await loadHeader(file).catch((e) => {
5252
error = e
5353
})
54-
assertObjectMatch(error, { key: 'NIFTI_HEADER_UNREADABLE' })
54+
assertObjectMatch(error, { code: 'NIFTI_HEADER_UNREADABLE' })
5555
})
5656

5757
await t.step('Tolerate big headers', async () => {

src/files/nifti.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export async function loadHeader(file: BIDSFile): Promise<NiftiHeader> {
4545
header.readHeader(data.buffer)
4646
}
4747
if (!header) {
48-
throw { key: 'NIFTI_HEADER_UNREADABLE' }
48+
throw { code: 'NIFTI_HEADER_UNREADABLE' }
4949
}
5050
const ndim = header.dims[0]
5151
return {
@@ -67,6 +67,6 @@ export async function loadHeader(file: BIDSFile): Promise<NiftiHeader> {
6767
sform_code: header.sform_code,
6868
} as NiftiHeader
6969
} catch (err) {
70-
throw { key: 'NIFTI_HEADER_UNREADABLE' }
70+
throw { code: 'NIFTI_HEADER_UNREADABLE' }
7171
}
7272
}

src/files/tsv.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Deno.test('TSV loading', async (t) => {
5353
try {
5454
await loadTSV(file)
5555
} catch (e: any) {
56-
assertObjectMatch(e, { key: 'TSV_EMPTY_LINE', line: 3 })
56+
assertObjectMatch(e, { code: 'TSV_EMPTY_LINE', line: 3 })
5757
}
5858
})
5959

@@ -64,7 +64,7 @@ Deno.test('TSV loading', async (t) => {
6464
try {
6565
await loadTSV(file)
6666
} catch (e: any) {
67-
assertObjectMatch(e, { key: 'TSV_EQUAL_ROWS', line: 3 })
67+
assertObjectMatch(e, { code: 'TSV_EQUAL_ROWS', location: '/mismatched_row.tsv', line: 3 })
6868
}
6969
})
7070

@@ -171,7 +171,7 @@ Deno.test('TSV loading', async (t) => {
171171
await loadTSV(file)
172172
assert(false, 'Expected error')
173173
} catch (e: any) {
174-
assertObjectMatch(e, { key: 'TSV_COLUMN_HEADER_DUPLICATE', evidence: 'a, a' })
174+
assertObjectMatch(e, { code: 'TSV_COLUMN_HEADER_DUPLICATE', issueMessage: 'a, a' })
175175
}
176176
})
177177

src/files/tsv.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ async function _loadTSV(file: BIDSFile, maxRows: number = -1): Promise<ColumnsMa
1919
const headers = (headerRow.done || !headerRow.value) ? [] : headerRow.value.split('\t')
2020

2121
if (new Set(headers).size !== headers.length) {
22-
throw { key: 'TSV_COLUMN_HEADER_DUPLICATE', evidence: headers.join(', ') }
22+
throw {
23+
code: 'TSV_COLUMN_HEADER_DUPLICATE',
24+
location: file.path,
25+
issueMessage: headers.join(', '),
26+
}
2327
}
2428

2529
// Initialize columns in array for construction efficiency
@@ -36,12 +40,12 @@ async function _loadTSV(file: BIDSFile, maxRows: number = -1): Promise<ColumnsMa
3640
if (!value) {
3741
const nextRow = await reader.read()
3842
if (nextRow.done) break
39-
throw { key: 'TSV_EMPTY_LINE', line: rowIndex + 2 }
43+
throw { code: 'TSV_EMPTY_LINE', location: file.path, line: rowIndex + 2 }
4044
}
4145

4246
const values = value.split('\t')
4347
if (values.length !== headers.length) {
44-
throw { key: 'TSV_EQUAL_ROWS', line: rowIndex + 2 }
48+
throw { code: 'TSV_EQUAL_ROWS', location: file.path, line: rowIndex + 2 }
4549
}
4650
columns.forEach((column, columnIndex) => {
4751
// Double array size if we exceed the current capacity

src/schema/associations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ export async function buildAssociations(
143143
// @ts-expect-error
144144
associations[key] = await load(file, { maxRows: context.dataset.options?.maxRows }).catch(
145145
(error: any) => {
146-
if (key in error) {
147-
context.dataset.issues.add({ code: error.key, location: file.path })
146+
if (error.code) {
147+
context.dataset.issues.add({ ...error, location: file.path })
148148
}
149149
},
150150
)

src/schema/context.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ export class BIDSContext implements Context {
210210
}
211211
for (const file of sidecars) {
212212
const json = await loadJSON(file).catch((error) => {
213-
if (error.key) {
214-
this.dataset.issues.add({ code: error.key, location: file.path })
213+
if (error.code) {
214+
this.dataset.issues.add({ ...error, location: file.path })
215215
return {}
216216
} else {
217217
throw error
@@ -232,8 +232,8 @@ export class BIDSContext implements Context {
232232
) return
233233

234234
this.nifti_header = await loadHeader(this.file).catch((error) => {
235-
if (error.key) {
236-
this.dataset.issues.add({ code: error.key, location: this.file.path })
235+
if (error.code) {
236+
this.dataset.issues.add({ ...error, location: this.file.path })
237237
return undefined
238238
} else {
239239
throw error
@@ -248,8 +248,8 @@ export class BIDSContext implements Context {
248248

249249
this.columns = await loadTSV(this.file, this.dataset.options?.maxRows)
250250
.catch((error) => {
251-
if (error.key) {
252-
this.dataset.issues.add({ code: error.key, location: this.file.path })
251+
if (error.code) {
252+
this.dataset.issues.add({ ...error, location: this.file.path })
253253
}
254254
logger.warn(
255255
`tsv file could not be opened by loadColumns '${this.file.path}'`,
@@ -272,8 +272,8 @@ export class BIDSContext implements Context {
272272
return
273273
}
274274
this.json = await loadJSON(this.file).catch((error) => {
275-
if (error.key) {
276-
this.dataset.issues.add({ code: error.key, location: this.file.path })
275+
if (error.code) {
276+
this.dataset.issues.add({ ...error, location: this.file.path })
277277
return {}
278278
} else {
279279
throw error
@@ -320,9 +320,10 @@ export class BIDSContext implements Context {
320320
const participants_tsv = this.dataset.tree.get('participants.tsv') as BIDSFile
321321
if (participants_tsv) {
322322
const participantsData = await loadTSV(participants_tsv)
323-
this.dataset.subjects.participant_id = participantsData[
324-
'participant_id'
325-
] as string[]
323+
.catch((error) => {
324+
return new Map()
325+
}) as Record<string, string[]>
326+
this.dataset.subjects.participant_id = participantsData['participant_id']
326327
}
327328

328329
// Load phenotype from phenotype/*.tsv
@@ -333,7 +334,10 @@ export class BIDSContext implements Context {
333334
const seen = new Set() as Set<string>
334335
for (const file of phenotypeFiles) {
335336
const phenotypeData = await loadTSV(file)
336-
const participant_id = phenotypeData['participant_id'] as string[]
337+
.catch((error) => {
338+
return new Map()
339+
}) as Record<string, string[]>
340+
const participant_id = phenotypeData['participant_id']
337341
if (participant_id) {
338342
participant_id.forEach((id) => seen.add(id))
339343
}

src/validators/bids.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ export async function validate(
5757
const dsContext = new BIDSContextDataset({ options, schema, tree: fileTree })
5858
if (ddFile) {
5959
dsContext.dataset_description = await loadJSON(ddFile).catch((error) => {
60-
if (error.key) {
61-
dsContext.issues.add({ code: error.key, location: ddFile.path })
60+
if (error.code) {
61+
dsContext.issues.add({ ...error, location: ddFile.path })
6262
return {} as Record<string, unknown>
6363
} else {
6464
throw error

0 commit comments

Comments
 (0)