Skip to content

Commit 2c7813f

Browse files
authored
Page Routes With Page and Line Class Refactor (#461)
* First pass at utilizing the Page and Line classes in the page routes * changes while reviewing * changes while reviewing * changes while reviewing * changes while reviewing * clean up and align error throughput * clean up and align error throughput * changes from testing * Really connect the wires after closer inspection * Really connect the wires after closer inspection * Really connect the wires after closer inspection * changes while revewing * changes while revewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes while testing and reviewing * Changes from standup * Changes from standup * Changes from standup * Changes during review * Changes during review
1 parent 06d4d45 commit 2c7813f

5 files changed

Lines changed: 251 additions & 201 deletions

File tree

classes/Line/Line.js

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const databaseTiny = new dbDriver("tiny")
55
export default class Line {
66

77
#tinyAction = 'create'
8+
#hydrated = false
89
#setRerumId() {
910
if (!this.id.startsWith(process.env.RERUMIDPREFIX)) {
1011
this.id = `${process.env.RERUMIDPREFIX}${this.id.split("/").pop()}`
@@ -51,36 +52,48 @@ export default class Line {
5152
throw new Error(`Failed to save Line to RERUM: ${err.message}`)
5253
})
5354
this.#tinyAction = 'update'
55+
this.#hydrated = true
5456
return this
5557
}
56-
// ...else Update the existing page in RERUM
57-
const existingLine = await fetch(this.id).then(res => res.json())
58-
.catch(err => {
59-
if (err.status === 404) {
60-
// If the line doesn't exist, we can create it
61-
return null
58+
// ...else Update the existing line in RERUM
59+
const existingLine = await fetch(this.id).then(async (resp) => {
60+
if (resp.ok) return resp.json()
61+
if (resp.status === 404) return null
62+
let rerumErrorMessage
63+
try {
64+
rerumErrorMessage = `${resp.status ?? 500}: ${this.id} - ${await resp.text()}`
65+
} catch (e) {
66+
rerumErrorMessage = `500: ${this.id} - A RERUM error occurred`
6267
}
63-
throw new Error(`Failed to fetch existing Line from RERUM: ${err.message}`)
68+
const err = new Error(rerumErrorMessage)
69+
err.status = 502
70+
throw err
6471
})
65-
66-
if (!existingLine) {
72+
.catch(err => {
73+
if (err.status === 502) throw err
74+
const genericRerumNetworkError = new Error(`500: ${this.id} - A RERUM error occurred`)
75+
genericRerumNetworkError.status = 502
76+
throw genericRerumNetworkError
77+
})
78+
if (!(existingLine?.id || existingLine?.["@id"])) {
6779
// This id doesn't exist in RERUM, so we need to create it
6880
this.#tinyAction = 'create'
6981
}
70-
7182
// Skip RERUM update if no content changes detected
7283
// Uses hasAnnotationChanges from shared.js instead of a private Class method for testability.
7384
if (existingLine && !hasAnnotationChanges(existingLine, lineAsAnnotation)) {
85+
this.#hydrated = true
7486
return this // Return without versioning
7587
}
76-
88+
const action = this.#tinyAction === 'create' ? 'save' : this.#tinyAction
7789
const updatedLine = existingLine ? { ...existingLine, ...lineAsAnnotation } : lineAsAnnotation
78-
const newURI = await databaseTiny[this.#tinyAction](updatedLine).then(res => res.id)
90+
const newURI = await databaseTiny[action](updatedLine).then(res => res.id)
7991
.catch(err => {
8092
throw new Error(`Failed to update Line in RERUM: ${err.message}`)
8193
})
8294
this.id = newURI
8395
this.#tinyAction = 'update'
96+
this.#hydrated = true
8497
return this
8598
}
8699

@@ -98,36 +111,41 @@ export default class Line {
98111
* Only RERUM URIs are supported.
99112
*/
100113
async #loadAnnotationDataFromRerum() {
101-
const rerumURI = this.id
102-
if (rerumURI.startsWith?.(process.env.RERUMIDPREFIX)) {
103-
const rawLineData = await fetch(rerumURI).then(async (resp) => {
114+
if (this.id.startsWith?.(process.env.RERUMIDPREFIX)) {
115+
const rawLineData = await fetch(this.id).then(async (resp) => {
104116
if (resp.ok) return resp.json()
105117
// The response from RERUM indicates a failure, likely with a specific code and textual body
106-
let rerumErrorMessage = `${resp.status ?? 500}: ${rerumURI} - `
118+
let rerumErrorMessage
107119
try {
108-
rerumErrorMessage += await resp.text()
120+
rerumErrorMessage = `${resp.status ?? 500}: ${this.id} - ${await resp.text()}`
121+
} catch (e) {
122+
rerumErrorMessage = `500: ${this.id} - A RERUM error occurred`
109123
}
110-
catch (err) {
111-
rerumErrorMessage = undefined
112-
}
113-
const err = new Error(rerumErrorMessage ?? `${resp.status ?? 500}: A RERUM error occurred for ${rerumURI}`)
124+
const err = new Error(rerumErrorMessage)
114125
err.status = 502
115126
throw err
116127
})
128+
.catch(err => {
129+
if (err.status === 502) throw err
130+
const genericRerumNetworkError = new Error(`500: ${this.id} - A RERUM error occurred`)
131+
genericRerumNetworkError.status = 502
132+
throw genericRerumNetworkError
133+
})
117134
if (!(rawLineData.id || rawLineData["@id"])) {
118135
// A 200 with garbled data, call it a fail
119-
const err = new Error(`A RERUM error occurred for ${rerumURI}`)
120-
err.status = 502
121-
throw err
136+
const genericRerumNetworkError = new Error(`500: ${this.id} - A RERUM error occurred`)
137+
genericRerumNetworkError.status = 502
138+
throw genericRerumNetworkError
122139
}
123140
// We don't have Class getters and setters for these properties...
124141
if ('body' in rawLineData) this.body = rawLineData.body
125-
if (rawLineData.target) this.target = rawLineData.target
142+
if ('target' in rawLineData) this.target = rawLineData.target
126143
if (rawLineData.creator) this.creator = rawLineData.creator
127144
if (rawLineData.motivation) this.motivation = rawLineData.motivation
128145
if (rawLineData.label) this.label = rawLineData.label
129146
if (rawLineData.type) this.type = rawLineData.type
130147
this.#tinyAction = 'update'
148+
this.#hydrated = true
131149
}
132150
return this
133151
}
@@ -237,19 +255,27 @@ export default class Line {
237255
}
238256

239257
async asJSON(isLD) {
240-
if (this.body === undefined) await this.#loadAnnotationDataFromRerum()
241-
return isLD ? {
242-
'@context': 'http://iiif.io/api/presentation/3/context.json',
243-
id: this.id,
244-
type: 'Annotation',
245-
motivation: this.motivation ?? 'transcribing',
246-
target: this.target,
247-
body: this.body,
248-
} : {
249-
id: this.id,
250-
body: this.body ?? '',
251-
target: this.target ?? '',
258+
if (!this.#hydrated) await this.#loadAnnotationDataFromRerum()
259+
let result
260+
if (isLD) {
261+
result = {
262+
'@context': 'http://iiif.io/api/presentation/3/context.json',
263+
id: this.id,
264+
type: 'Annotation',
265+
motivation: this.motivation ?? 'transcribing',
266+
target: this.target,
267+
body: this.body,
268+
}
269+
if (this.creator) result.creator = this.creator
270+
}
271+
else {
272+
result = {
273+
id: this.id,
274+
body: this.body ?? '',
275+
target: this.target ?? '',
276+
}
252277
}
278+
return result
253279
}
254280

255281
asHTML() {
@@ -262,7 +288,7 @@ export default class Line {
262288
* @returns {string} The text content of the Line, or empty string if no textual body exists.
263289
*/
264290
async asTextBlob() {
265-
if (this.body === undefined) await this.#loadAnnotationDataFromRerum()
291+
if (!this.#hydrated) await this.#loadAnnotationDataFromRerum()
266292
return extractTextFromAnnotationBody(this.body)
267293
}
268294

0 commit comments

Comments
 (0)