Skip to content

Commit

Permalink
Restore aborting.ts to avoid breakage
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Nov 18, 2024
1 parent 9e417b3 commit e46c501
Showing 1 changed file with 68 additions and 2 deletions.
70 changes: 68 additions & 2 deletions packages/core/util/aborting.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,77 @@
import { Observable, fromEvent } from 'rxjs'

class AbortError extends Error {
public code: string | undefined
}

/**
* properly check if the given AbortSignal is aborted. per the standard, if the
* signal reads as aborted, this function throws either a DOMException
* AbortError, or a regular error with a `code` attribute set to `ERR_ABORTED`.
*
* for convenience, passing `undefined` is a no-op
*
* @param signal -
* @returns nothing
*/
export function checkAbortSignal(signal?: AbortSignal): void {
if (!signal) {
return
}

if (!(signal instanceof AbortSignal)) {
throw new TypeError('must pass an AbortSignal')
}

if (signal.aborted) {
throw makeAbortError()
}
}

function timeout(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
/**
* Skips to the next tick, then runs `checkAbortSignal`.
* Await this to inside an otherwise synchronous loop to
* provide a place to break when an abort signal is received.
*/
export async function abortBreakPoint(signal?: AbortSignal) {
// it was observed that an actual timeout is needed to get the aborting (wrap
// hicrenderer in a try catch, console.error the error, and rethrow the error
// to see). using await Promise.resolve() did not appear to allow aborting to
// occur
await timeout(1)
checkAbortSignal(signal)
}

export function makeAbortError() {
if (typeof DOMException !== 'undefined') {
return new DOMException('aborted', 'AbortError')
}
const e = new AbortError('aborted')
e.code = 'ERR_ABORTED'
return e
}

export function observeAbortSignal(signal?: AbortSignal): Observable<Event> {
if (!signal) {
return new Observable()
}
return fromEvent(signal, 'abort')
}

/**
* check if the given exception was caused by an operation being intentionally aborted
* @param exception -
*/
export function isAbortException(exception: unknown): boolean {
return (
exception instanceof Error &&
// DOMException
(exception.name === 'AbortError' ||
// standard-ish non-DOM abort exception
// @ts-expect-error
exception.code === 'ERR_ABORTED' ||
(exception as AbortError).code === 'ERR_ABORTED' ||
// message contains aborted for bubbling through RPC
// things we have seen that we want to catch here
// Error: aborted
Expand Down

0 comments on commit e46c501

Please sign in to comment.