| 758 | } |
| 759 | |
| 760 | override _destroy(error: Error | null, callback: (error: Error | null) => void): void { // eslint-disable-line @typescript-eslint/no-restricted-types |
| 761 | this._stopReading = true; |
| 762 | this.flush = async () => {}; |
| 763 | |
| 764 | // Prevent further retries |
| 765 | this._stopRetry?.(); |
| 766 | this._cancelTimeouts?.(); |
| 767 | this._abortListenerDisposer?.[Symbol.dispose](); |
| 768 | |
| 769 | if (this.options) { |
| 770 | const {body} = this.options; |
| 771 | if (is.nodeStream(body)) { |
| 772 | body.destroy(); |
| 773 | } |
| 774 | } |
| 775 | |
| 776 | if (this._request) { |
| 777 | this._request.destroy(); |
| 778 | } |
| 779 | |
| 780 | // Workaround: http-timer only sets timings.end when the response emits 'end'. |
| 781 | // When a stream is destroyed before completion, the 'end' event may not fire, |
| 782 | // leaving timings.end undefined. This should ideally be fixed in http-timer |
| 783 | // by listening to the 'close' event, but we handle it here for now. |
| 784 | // Only set timings.end if there was no error or abort (to maintain semantic correctness). |
| 785 | const timings = (this._request as ClientRequestWithTimings)?.timings; |
| 786 | if (timings && is.undefined(timings.end) && !is.undefined(timings.response) && is.undefined(timings.error) && is.undefined(timings.abort)) { |
| 787 | timings.end = Date.now(); |
| 788 | if (is.undefined(timings.phases.total)) { |
| 789 | timings.phases.download = timings.end - timings.response; |
| 790 | timings.phases.total = timings.end - timings.start; |
| 791 | } |
| 792 | } |
| 793 | |
| 794 | // Preserve custom errors returned by beforeError hooks. |
| 795 | // For other errors, wrap non-RequestError instances for consistency. |
| 796 | if (error !== null && !is.undefined(error)) { |
| 797 | const processedByHooks = error instanceof Error && errorsProcessedByHooks.has(error); |
| 798 | |
| 799 | if (!processedByHooks && !(error instanceof RequestError)) { |
| 800 | error = error instanceof Error |
| 801 | ? new RequestError(error.message, error, this) |
| 802 | : new RequestError(String(error), {}, this); |
| 803 | } |
| 804 | } |
| 805 | |
| 806 | callback(error); |
| 807 | } |
| 808 | |
| 809 | override pipe<T extends NodeJS.WritableStream>(destination: T, options?: {end?: boolean}): T { |
| 810 | if (destination instanceof ServerResponse) { |