72 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {onAbortedSignal} from '../utils/abort-signal.js';
 | |
| import {sendAbort} from '../ipc/graceful.js';
 | |
| import {killOnTimeout} from './kill.js';
 | |
| 
 | |
| // Validate the `gracefulCancel` option
 | |
| export const validateGracefulCancel = ({gracefulCancel, cancelSignal, ipc, serialization}) => {
 | |
| 	if (!gracefulCancel) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (cancelSignal === undefined) {
 | |
| 		throw new Error('The `cancelSignal` option must be defined when setting the `gracefulCancel` option.');
 | |
| 	}
 | |
| 
 | |
| 	if (!ipc) {
 | |
| 		throw new Error('The `ipc` option cannot be false when setting the `gracefulCancel` option.');
 | |
| 	}
 | |
| 
 | |
| 	if (serialization === 'json') {
 | |
| 		throw new Error('The `serialization` option cannot be \'json\' when setting the `gracefulCancel` option.');
 | |
| 	}
 | |
| };
 | |
| 
 | |
| // Send abort reason to the subprocess when aborting the `cancelSignal` option and `gracefulCancel` is `true`
 | |
| export const throwOnGracefulCancel = ({
 | |
| 	subprocess,
 | |
| 	cancelSignal,
 | |
| 	gracefulCancel,
 | |
| 	forceKillAfterDelay,
 | |
| 	context,
 | |
| 	controller,
 | |
| }) => gracefulCancel
 | |
| 	? [sendOnAbort({
 | |
| 		subprocess,
 | |
| 		cancelSignal,
 | |
| 		forceKillAfterDelay,
 | |
| 		context,
 | |
| 		controller,
 | |
| 	})]
 | |
| 	: [];
 | |
| 
 | |
| const sendOnAbort = async ({subprocess, cancelSignal, forceKillAfterDelay, context, controller: {signal}}) => {
 | |
| 	await onAbortedSignal(cancelSignal, signal);
 | |
| 	const reason = getReason(cancelSignal);
 | |
| 	await sendAbort(subprocess, reason);
 | |
| 	killOnTimeout({
 | |
| 		kill: subprocess.kill,
 | |
| 		forceKillAfterDelay,
 | |
| 		context,
 | |
| 		controllerSignal: signal,
 | |
| 	});
 | |
| 	context.terminationReason ??= 'gracefulCancel';
 | |
| 	throw cancelSignal.reason;
 | |
| };
 | |
| 
 | |
| // The default `reason` is a DOMException, which is not serializable with V8
 | |
| // See https://github.com/nodejs/node/issues/53225
 | |
| const getReason = ({reason}) => {
 | |
| 	if (!(reason instanceof DOMException)) {
 | |
| 		return reason;
 | |
| 	}
 | |
| 
 | |
| 	const error = new Error(reason.message);
 | |
| 	Object.defineProperty(error, 'stack', {
 | |
| 		value: reason.stack,
 | |
| 		enumerable: false,
 | |
| 		configurable: true,
 | |
| 		writable: true,
 | |
| 	});
 | |
| 	return error;
 | |
| };
 |