Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ function Body() {
/*
fetch-mock wraps the Response object in an ES6 Proxy to
provide useful test harness features such as flush. However, on
ES5 browsers without fetch or Proxy support pollyfills must be used;
the proxy-pollyfill is unable to proxy an attribute unless it exists
ES5 browsers without fetch or Proxy support polyfills must be used;
the proxy-polyfill is unable to proxy an attribute unless it exists
on the object before the Proxy is created. This change ensures
Response.bodyUsed exists on the instance, while maintaining the
semantic of setting Request.bodyUsed in the constructor before
Expand Down Expand Up @@ -528,6 +528,9 @@ export function fetch(input, init) {
var request = new Request(input, init)

if (request.signal && request.signal.aborted) {
if (request.signal.throwIfAborted) {
request.signal.throwIfAborted()
}
return reject(new DOMException('Aborted', 'AbortError'))
}

Expand Down Expand Up @@ -570,7 +573,15 @@ export function fetch(input, init) {

xhr.onabort = function() {
setTimeout(function() {
reject(new DOMException('Aborted', 'AbortError'))
if (request.signal && request.signal.aborted && request.signal.throwIfAborted) {
try {
request.signal.throwIfAborted()
} catch (e) {
reject(e)
}
} else {
reject(new DOMException('Aborted', 'AbortError'))
}
}, 0)
}

Expand Down
119 changes: 119 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,49 @@ exercise.forEach(function(exerciseMode) {
)
})

test('initially timed-out signal', function() {
var signal = AbortSignal.timeout(0)
var sleep = new Promise((resolve) => {
setTimeout(function() {
resolve()
}, 10)
})

return sleep.then(function() {
return fetch('/request', {signal})
}).then(
function() {
assert.ok(false)
},
function(error) {
if (!IEorEdge) assert.instanceOf(error, WHATWGFetch.DOMException)
assert.equal(error.name, 'TimeoutError')
}
)
})

test('initially timed-out signal within Request', function() {
var signal = AbortSignal.timeout(0)
var sleep = new Promise((resolve) => {
setTimeout(function() {
resolve()
}, 10)
})

return sleep.then(function() {
var request = new Request('/request', {signal})
return fetch(request)
}).then(
function() {
assert.ok(false)
},
function(error) {
if (!IEorEdge) assert.instanceOf(error, WHATWGFetch.DOMException)
assert.equal(error.name, 'TimeoutError')
}
)
})

test('mid-request', function() {
var controller = new AbortController()

Expand Down Expand Up @@ -1275,6 +1318,82 @@ exercise.forEach(function(exerciseMode) {
)
})

test('mid-request with custom abort reason', function() {
var controller = new AbortController()

setTimeout(function() {
controller.abort('CustomReason')
}, 30)

return fetch('/slow?_=' + new Date().getTime(), {
signal: controller.signal
}).then(
function() {
assert.ok(false)
},
function(error) {
// https://bugs.webkit.org/show_bug.cgi?id=246069
if (Safari && exerciseMode === 'native') {
assert.equal(error.name, 'AbortError')
} else {
assert.equal(error, 'CustomReason')
}
}
)
})

test('mid-request with custom abort reason within Request', function() {
var controller = new AbortController()
var request = new Request('/slow?_=' + new Date().getTime(), {signal: controller.signal})

setTimeout(function() {
controller.abort('CustomReason')
}, 30)

return fetch(request).then(
function() {
assert.ok(false)
},
function(error) {
// https://bugs.webkit.org/show_bug.cgi?id=246069
if (Safari && exerciseMode === 'native') {
assert.equal(error.name, 'AbortError')
} else {
assert.equal(error, 'CustomReason')
}
}
)
})

test('mid-request timeout', function() {
return fetch('/slow?_=' + new Date().getTime(), {
signal: AbortSignal.timeout(30)
}).then(
function() {
assert.ok(false)
},
function(error) {
// https://bugs.webkit.org/show_bug.cgi?id=246069
const expected = (Safari && exerciseMode === 'native') ? 'AbortError' : 'TimeoutError'
assert.equal(error.name, expected)
}
)
})

test('mid-request timeout within Request', function() {
var request = new Request('/slow?_=' + new Date().getTime(), {signal: AbortSignal.timeout(30)})
return fetch(request).then(
function() {
assert.ok(false)
},
function(error) {
// https://bugs.webkit.org/show_bug.cgi?id=246069
const expected = (Safari && exerciseMode === 'native') ? 'AbortError' : 'TimeoutError'
assert.equal(error.name, expected)
}
)
})

test('abort multiple with same signal', function() {
var controller = new AbortController()

Expand Down