diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2025-05-05 23:12:22 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2025-05-05 23:14:57 -0400 |
| commit | 84c1fa7ccef4e8e49f17d643f360ec0f184683fb (patch) | |
| tree | 697a2f2c4f7f2b04f581023d82212c4c74877920 /ui/lib/outbox.svelte.js | |
| parent | d11ff421de581a835f1645b22d1f7f4304640b0c (diff) | |
Don't retry operations where we received an unacceptable response.
This was actually two issues in one!
Issue 1: `isRetryable` did not consider whether we got a response or not. It assumed that the presence of a request in the error signaled that the error was definitely due to network issues, when in fact it's the presence of a request _and_ the absence of a response. That's my misreading of the Axios docs; the replacement `isRetryable` is more thorough.
Issue 2: operations in the outbox queue that fail with an exception stop the outbox drain process from making further progress, _and_ they stay in the queue. The outbox now dequeues jobs that throw an exception, and restarts itself if it terminates with a non-empty queue. The code that does this is _heinous_, but it seems to work well enough… Words I'm sure I won't come to regret.
Diffstat (limited to 'ui/lib/outbox.svelte.js')
| -rw-r--r-- | ui/lib/outbox.svelte.js | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/ui/lib/outbox.svelte.js b/ui/lib/outbox.svelte.js index de7f80e..fd7fdba 100644 --- a/ui/lib/outbox.svelte.js +++ b/ui/lib/outbox.svelte.js @@ -69,6 +69,14 @@ export class Outbox { // rather than spreading it across multiple methods. this.sending = this.drain().finally(() => { this.sending = null; + + // If we encounter an exception processing the pending queue, it may have an operation left + // in it. If so, start over. The exception will still propagate out (though since nothing + // ever awaits the promise from this.sending, it'll ultimately leak out to the browser + // anyways). + if (this.pending.length > 0) { + this.start(); + } }); } @@ -76,8 +84,11 @@ export class Outbox { while (this.pending.length > 0) { const operation = this.pending[0]; - await operation.send(); - this.pending.shift(); + try { + await operation.send(); + } finally { + this.pending.shift(); + } } } } |
