diff --git a/source/core/options.ts b/source/core/options.ts index aa43ee1c3..c5fdb27d0 100644 --- a/source/core/options.ts +++ b/source/core/options.ts @@ -776,20 +776,25 @@ export default class Options { try { if (is.plainObject(input)) { - this.merge(input); - this.merge(options); - this.url = input.url; + try { + this.merge(input); + this.merge(options); + } finally { + this.url = input.url; + } } else { - this.merge(options); - - if (options?.url !== undefined) { - if (input === undefined) { - this.url = options.url; - } else { - throw new TypeError('The `url` option is mutually exclusive with the `input` argument'); + try { + this.merge(options); + } finally { + if (options?.url !== undefined) { + if (input === undefined) { + this.url = options.url; + } else { + throw new TypeError('The `url` option is mutually exclusive with the `input` argument'); + } + } else if (input !== undefined) { + this.url = input; } - } else if (input !== undefined) { - this.url = input; } } } catch (error) { diff --git a/test/arguments.ts b/test/arguments.ts index 647ba5ee0..1a531be08 100644 --- a/test/arguments.ts +++ b/test/arguments.ts @@ -2,7 +2,7 @@ import {parse, URL, URLSearchParams} from 'url'; import test from 'ava'; import {Handler} from 'express'; import pEvent from 'p-event'; -import got, {Options, StrictOptions} from '../source/index.js'; +import got, {Options, RequestError, StrictOptions} from '../source/index.js'; import withServer, {withBodyParsingServer} from './helpers/with-server.js'; import invalidUrl from './helpers/invalid-url.js'; @@ -600,3 +600,28 @@ test('throws on too large noise', t => { /* eslint-enable no-new */ }); + +test('options have url even if some are invalid', async t => { + const error = await t.throwsAsync(got('https://example.com', { + // @ts-expect-error + invalid: true + })); + + t.is((error.options.url as URL).href, 'https://example.com/'); +}); + +test('options have url even if some are invalid - got.extend', async t => { + const instance = got.extend({ + handlers: [ + (options, next) => { + t.is((options.url as URL).href, 'https://example.com/'); + return next(options); + } + ] + }); + + await t.throwsAsync(instance('https://example.com', { + // @ts-expect-error + invalid: true + })); +});