@evanp/activitypub-bot 0.32.1 → 0.32.2

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.
@@ -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(res.status, `Could not fetch ${url}`)
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(res.status, await res.text())
179
+ throw createHttpError(
180
+ res.status,
181
+ await res.text(),
182
+ { headers: res.headers }
183
+ )
176
184
  }
177
185
  }
178
186
 
@@ -58,7 +58,28 @@ export class DistributionWorker {
58
58
  { error, activity: activity.id, inbox },
59
59
  'Could not deliver activity due to client error'
60
60
  )
61
- await this.#jobQueue.fail(jobId, this.#workerId)
61
+ if (error.status === 429) {
62
+ this.#logger.debug(
63
+ { error, activity: activity.id, inbox },
64
+ 'Retrying on 429 status'
65
+ )
66
+ let delay
67
+ if (error.headers && error.headers['retry-after']) {
68
+ this.#logger.debug('using retry-after header')
69
+ const retryAfter = error.headers['retry-after']
70
+ if (/^\d+$/.test(retryAfter)) {
71
+ delay = parseInt(retryAfter, 10) * 1000
72
+ } else {
73
+ delay = new Date(retryAfter) - Date.now()
74
+ }
75
+ } else {
76
+ this.#logger.debug('exponential backoff')
77
+ delay = Math.round((2 ** (attempts - 1) * 1000) * (0.5 + Math.random()))
78
+ }
79
+ await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
80
+ } else {
81
+ await this.#jobQueue.fail(jobId, this.#workerId)
82
+ }
62
83
  } else if (error.status >= 500 && error.status < 600) {
63
84
  if (attempts >= DistributionWorker.#MAX_ATTEMPTS) {
64
85
  this.#logger.warn(
@@ -74,6 +95,12 @@ export class DistributionWorker {
74
95
  )
75
96
  await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
76
97
  }
98
+ } else {
99
+ this.#logger.warn(
100
+ { error, activity: activity.id, inbox },
101
+ 'Could not deliver activity due to unexpected status range'
102
+ )
103
+ await this.#jobQueue.fail(jobId, this.#workerId)
77
104
  }
78
105
  }
79
106
  } catch (err) {
@@ -83,7 +110,12 @@ export class DistributionWorker {
83
110
  }
84
111
  this.#logger.warn({ err, jobId }, 'Error delivering to bot')
85
112
  if (jobId) {
86
- await this.#jobQueue.release(jobId, this.#workerId)
113
+ const delay = Math.round((2 ** ((attempts ?? 1) - 1) * 1000) * (0.5 + Math.random()))
114
+ this.#logger.warn(
115
+ { err, jobId, attempts, delay },
116
+ 'Retrying job after a delay'
117
+ )
118
+ await this.#jobQueue.retryAfter(jobId, this.#workerId, delay)
87
119
  }
88
120
  }
89
121
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evanp/activitypub-bot",
3
- "version": "0.32.1",
3
+ "version": "0.32.2",
4
4
  "description": "server-side ActivityPub bot framework",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",