@evanp/activitypub-bot 0.32.1 → 0.32.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/activitypubclient.js +10 -2
- package/lib/distributionworker.js +44 -4
- package/package.json +1 -1
package/lib/activitypubclient.js
CHANGED
|
@@ -108,7 +108,11 @@ export class ActivityPubClient {
|
|
|
108
108
|
if (res.status < 200 || res.status > 299) {
|
|
109
109
|
const body = await res.text()
|
|
110
110
|
this.#logger.warn({ status: res.status, body, url }, 'Could not fetch url')
|
|
111
|
-
throw createHttpError(
|
|
111
|
+
throw createHttpError(
|
|
112
|
+
res.status,
|
|
113
|
+
`Could not fetch ${url}`,
|
|
114
|
+
{ headers: res.headers }
|
|
115
|
+
)
|
|
112
116
|
}
|
|
113
117
|
const contentType = res.headers.get('content-type')
|
|
114
118
|
const mimeType = contentType?.split(';')[0].trim()
|
|
@@ -172,7 +176,11 @@ export class ActivityPubClient {
|
|
|
172
176
|
await this.#limiter.update(hostname, res.headers)
|
|
173
177
|
this.#logger.debug(`Done fetching POST for ${url}`)
|
|
174
178
|
if (res.status < 200 || res.status > 299) {
|
|
175
|
-
throw createHttpError(
|
|
179
|
+
throw createHttpError(
|
|
180
|
+
res.status,
|
|
181
|
+
await res.text(),
|
|
182
|
+
{ headers: res.headers }
|
|
183
|
+
)
|
|
176
184
|
}
|
|
177
185
|
}
|
|
178
186
|
|
|
@@ -58,22 +58,43 @@ export class DistributionWorker {
|
|
|
58
58
|
{ error, activity: activity.id, inbox },
|
|
59
59
|
'Could not deliver activity due to client error'
|
|
60
60
|
)
|
|
61
|
-
|
|
61
|
+
if ([408, 425, 429].includes(error.status)) {
|
|
62
|
+
this.#logger.debug(
|
|
63
|
+
{ error, activity: activity.id, inbox },
|
|
64
|
+
'Retrying on recoverable status'
|
|
65
|
+
)
|
|
66
|
+
const delay = this.#retryDelay(error.headers, attempts)
|
|
67
|
+
await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
|
|
68
|
+
} else {
|
|
69
|
+
await this.#jobQueue.fail(jobId, this.#workerId)
|
|
70
|
+
}
|
|
62
71
|
} else if (error.status >= 500 && error.status < 600) {
|
|
63
|
-
if (
|
|
72
|
+
if ([501, 505, 508, 510].includes(error.status)) {
|
|
73
|
+
this.#logger.warn(
|
|
74
|
+
{ error, activity: activity.id, inbox, attempts },
|
|
75
|
+
'Could not deliver activity due to unrecoverable server error'
|
|
76
|
+
)
|
|
77
|
+
await this.#jobQueue.fail(jobId, this.#workerId)
|
|
78
|
+
} else if (attempts >= DistributionWorker.#MAX_ATTEMPTS) {
|
|
64
79
|
this.#logger.warn(
|
|
65
80
|
{ error, activity: activity.id, inbox, attempts },
|
|
66
81
|
'Could not deliver activity due to server error; no more attempts'
|
|
67
82
|
)
|
|
68
83
|
await this.#jobQueue.fail(jobId, this.#workerId)
|
|
69
84
|
} else {
|
|
70
|
-
const delay =
|
|
85
|
+
const delay = this.#retryDelay(error.headers, attempts)
|
|
71
86
|
this.#logger.warn(
|
|
72
87
|
{ error, activity: activity.id, inbox, attempts, delay },
|
|
73
88
|
'Could not deliver activity due to server error; will retry'
|
|
74
89
|
)
|
|
75
90
|
await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
|
|
76
91
|
}
|
|
92
|
+
} else {
|
|
93
|
+
this.#logger.warn(
|
|
94
|
+
{ error, activity: activity.id, inbox },
|
|
95
|
+
'Could not deliver activity due to unexpected status range'
|
|
96
|
+
)
|
|
97
|
+
await this.#jobQueue.fail(jobId, this.#workerId)
|
|
77
98
|
}
|
|
78
99
|
}
|
|
79
100
|
} catch (err) {
|
|
@@ -83,12 +104,31 @@ export class DistributionWorker {
|
|
|
83
104
|
}
|
|
84
105
|
this.#logger.warn({ err, jobId }, 'Error delivering to bot')
|
|
85
106
|
if (jobId) {
|
|
86
|
-
|
|
107
|
+
const delay = this.#retryDelay(null, attempts ?? 1)
|
|
108
|
+
this.#logger.warn(
|
|
109
|
+
{ err, jobId, attempts, delay },
|
|
110
|
+
'Retrying job after a delay'
|
|
111
|
+
)
|
|
112
|
+
await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
115
|
}
|
|
90
116
|
}
|
|
91
117
|
|
|
118
|
+
#retryDelay (headers, attempts) {
|
|
119
|
+
if (headers?.['retry-after']) {
|
|
120
|
+
this.#logger.debug('using retry-after header')
|
|
121
|
+
const retryAfter = headers['retry-after']
|
|
122
|
+
if (/^\d+$/.test(retryAfter)) {
|
|
123
|
+
return parseInt(retryAfter, 10) * 1000
|
|
124
|
+
} else {
|
|
125
|
+
return new Date(retryAfter) - Date.now()
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
this.#logger.debug('exponential backoff')
|
|
129
|
+
return Math.round((2 ** (attempts - 1) * 1000) * (0.5 + Math.random()))
|
|
130
|
+
}
|
|
131
|
+
|
|
92
132
|
stop () {
|
|
93
133
|
this.#running = false
|
|
94
134
|
}
|