-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feature($http): allow differentiation between Request Error, Abort and Timeout #15847
Conversation
Travis fails:
|
src/ngMock/angular-mocks.js
Outdated
if (angular.isFunction(status)) return status; | ||
|
||
return function() { | ||
return angular.isNumber(status) | ||
? [status, data, headers, statusText] | ||
? [status, data, headers, statusText, xhrStatus] | ||
: [200, status, data, headers]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No xhrStatus
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, I could put a hardcoded 'success' there. But as 200 is already hardcoded, I was getting confused whether or not xhrStatus needs to be here.
src/ngMock/angular-mocks.js
Outdated
@@ -1381,15 +1381,22 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { | |||
function handleResponse() { | |||
var response = wrapped.response(method, url, data, headers, wrapped.params(url)); | |||
xhr.$$respHeaders = response[2]; | |||
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why we are coyping stuff that theoretically are primitive (such as status
, statusText
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copy was already there, I added the extra param in the same way. But yes, I was wondering the exact same thing. Maybe there used to be a reason :D
src/ngMock/angular-mocks.js
Outdated
@@ -1381,15 +1381,22 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { | |||
function handleResponse() { | |||
var response = wrapped.response(method, url, data, headers, wrapped.params(url)); | |||
xhr.$$respHeaders = response[2]; | |||
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), | |||
var xhrStatus = copy(response[4]); | |||
if (xhrStatus) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the different code-paths?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently, I forgot to push things at home. I've fixed this already. I'll push it in 2 hours (+/-).
This was the quick and dirty check I did in order to stay backwards compatible (and not break 60 tests). But it's a better idea to break and fix them for this change.
So I've reduced it to a single path and fixed all 60+ braking tests.
src/ngMock/angular-mocks.js
Outdated
if (angular.isFunction(status)) return status; | ||
|
||
return function() { | ||
return angular.isNumber(status) | ||
? [status, data, headers, statusText] | ||
: [200, status, data, headers]; | ||
? [status, data, headers, statusText, xhrStatus || (status === 200 ? 'success' : 'error')] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkalpak It feels abit odd to be calculating xhrStatus (the above example isn't what it should be yet). I went down the path of an hardcoded 'success' value because of the hardcoded 200
on line 1350. Hardcoding 'success' made me wonder if we should be calculating xhrStatus based on status (if xhrStatus was not provided). But it brings some (unnessecary?) complexity in here.
Maybe it's a good idea to not set any xhrStatus based on the status, apart from the hardcoded 'success' on line 1350, and change this line (1349) to [status, data, headers, statusText, xhrStatus]
keeping xhrStatus
undefined if not provided, unless status
is not a number (then xhrStatus would be 'success'). But this doesn't sound very consistent ... 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since xhrStatus
is something that is generated by $httpBackend
(i.e. it is not something that comes from the server, I think we should not even make it "trainable". I.e. you should:
- Remove the
xhrStatus
argument fromcreateResponse
(and other similar places). - Generate
xhrStatus
insidecreateResponse
, based on the same rules we use in$httpBackend
(i.e.200 <= status < 300 ? 'success' : 'error'
). - Update existing tests. Add new tests that verify this new behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error
as of 3xx or 4xx ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized 'success'
is confusing. I was thinking it means something different than it actually does. Maybe we should change it to complete
or something.
Then you should change both lines to xhrStatus || 'complete'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So does that mean that response 300 up to 500 are to be considered not completed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, all responses are considered 'complete' ('complete' means that the request completed, i.e. a response was received from the server, regardless of what the status of the response was).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then you should change both lines to xhrStatus || 'complete'.
Does it still make sense to use xhrStatus || 'complete'
?
function createResponse(status, data, headers, statusText, xhrStatus) {
if (angular.isFunction(status)) return status;
return function() {
return angular.isNumber(status)
? [status, data, headers, statusText, xhrStatus || 'complete']
: [200, status, data, headers, xhrStatus || 'complete'];
};
}
As we're always returning a status code, I guess we can consider it 'complete' in both situations? This would be in line with how this change is currently implemented in$httpBackend
(none-mock).
Or is there any need to manually set the xhrStatus to anything else but 'complete' when using .respone()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOL - I contradict myself in these comments: #15847 (comment)
#15847 (comment)
It doesn't make sense to make it configurable imo, so let's remove the xhrStatus
argument and make it 'complete'
everywhere.
src/ngMock/angular-mocks.js
Outdated
if (angular.isFunction(status)) return status; | ||
|
||
return function() { | ||
return angular.isNumber(status) | ||
? [status, data, headers, statusText] | ||
: [200, status, data, headers]; | ||
? [status, data, headers, statusText, xhrStatus || (status === 200 ? 'success' : 'error')] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since xhrStatus
is something that is generated by $httpBackend
(i.e. it is not something that comes from the server, I think we should not even make it "trainable". I.e. you should:
- Remove the
xhrStatus
argument fromcreateResponse
(and other similar places). - Generate
xhrStatus
insidecreateResponse
, based on the same rules we use in$httpBackend
(i.e.200 <= status < 300 ? 'success' : 'error'
). - Update existing tests. Add new tests that verify this new behavior.
@frederikprijck do you need help on this one? |
@gkalpak I see this is labelled as "needs breaking change". I can't see how this is breaking atm :/ |
src/ngMock/angular-mocks.js
Outdated
@@ -1382,14 +1382,14 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { | |||
var response = wrapped.response(method, url, data, headers, wrapped.params(url)); | |||
xhr.$$respHeaders = response[2]; | |||
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), | |||
copy(response[3] || '')); | |||
copy(response[3] || ''), copy(response[4])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with the 7-space indentation? 😕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the linter agrees so ... 🙈 (on a serious note: no clue, I'll get it removed before merging)
@Narretz, (although not likely) it could break tests that assert an const mySpy = jasmine.createSpy('mySpy');
$httpBackend.whenGET('/foo').respond('bar');
$http.get('/foo').then(mySpy);
$httpBackend.flush();
expect(mySpy).toHaveBeenCalledWith({
data: 'bar',
status: 200,
statusText: '',
headers: jasmine.any(Function),
config: jasmine.any(Object),
}); This would previously pass, but it will fail with this change because the I admit the possibility this affects anyone is tiny, but still possible. I added the label, so we can discuss it when the time comes (which is about now 😃). |
i think the feature is too useful and the possible breaking change to minor to put this into 1.7. I'd say put it into 1.6 |
OK. Let's do this 😃 |
…rt, timeout Previously, it wasn't possible to tell if an `$http`-initiated XMLHttpRequest was completed normally or with an error or it was aborted or timed out. This commit adds a new property on the `response` object (`xhrStatus`) which allows to defferentiate between the possible statuses. Fixes #15924 Closes #15847
did this end up in a release somewhere? |
This is a continuation of #15626