Skip to content

Commit 64f3001

Browse files
committed
If xhr.response errors, callback with error.
Fixes d3#1263. Previously, if d3.json was used to load invalid JSON, a SyntaxError would be thrown. Now an error is reported to the callback instead, in the same manner as if a network error occurred. This allows the caller to handle the invalid response, rather than throwing an asynchronous error.
1 parent eb38418 commit 64f3001

4 files changed

Lines changed: 42 additions & 10 deletions

File tree

d3.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,8 +1634,18 @@ d3 = function() {
16341634
request.readyState > 3 && respond();
16351635
};
16361636
function respond() {
1637-
var s = request.status;
1638-
!s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
1637+
var status = request.status, result;
1638+
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) {
1639+
try {
1640+
result = response.call(xhr, request);
1641+
} catch (e) {
1642+
dispatch.error.call(xhr, e);
1643+
return;
1644+
}
1645+
dispatch.load.call(xhr, result);
1646+
} else {
1647+
dispatch.error.call(xhr, request);
1648+
}
16391649
}
16401650
request.onprogress = function(event) {
16411651
var o = d3.event;

d3.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/xhr/xhr.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,18 @@ d3.xhr = function(url, mimeType, callback) {
1616
: request.onreadystatechange = function() { request.readyState > 3 && respond(); };
1717

1818
function respond() {
19-
var s = request.status;
20-
!s && request.responseText || s >= 200 && s < 300 || s === 304
21-
? dispatch.load.call(xhr, response.call(xhr, request))
22-
: dispatch.error.call(xhr, request);
19+
var status = request.status, result;
20+
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) {
21+
try {
22+
result = response.call(xhr, request);
23+
} catch (e) {
24+
dispatch.error.call(xhr, e);
25+
return;
26+
}
27+
dispatch.load.call(xhr, result);
28+
} else {
29+
dispatch.error.call(xhr, request);
30+
}
2331
}
2432

2533
request.onprogress = function(event) {

test/xhr/json-test.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,25 @@ suite.addBatch({
2424
topic: function(json) {
2525
var callback = this.callback;
2626
json("//does/not/exist.json", function(error, json) {
27-
callback(null, json);
27+
callback(null, {error: error, value: json});
2828
});
2929
},
30-
"invokes the callback with undefined when an error occurs": function(json) {
31-
assert.isUndefined(json);
30+
"invokes the callback with undefined when an error occurs": function(result) {
31+
assert.equal(result.error.status, 404);
32+
assert.isUndefined(result.value);
33+
}
34+
},
35+
36+
"on a file with invalid JSON": {
37+
topic: function(json) {
38+
var callback = this.callback;
39+
json("test/data/sample.tsv", function(error, json) {
40+
callback(null, {error: error, value: json});
41+
});
42+
},
43+
"invokes the callback with undefined when an error occurs": function(result) {
44+
assert.equal(result.error.constructor.name, "SyntaxError");
45+
assert.isUndefined(result.value);
3246
}
3347
}
3448
}

0 commit comments

Comments
 (0)