The upgrade of React – Apollo was delayed until now, and v1 was used all the time. With the upgrade of React, I was really afraid that it would hinder the upgrade of React, so Q decided to upgrade it.
Migrate V2 files here. You can migrate V2 quickly. After the replacement is complete, startup discovery can run normally. However, the status of the server will return 401, 403, and 405
Problems arise
According to the documentation, the 4XX state is handled like this:
const errorLink = onError(({ networkError = {}, graphQLErrors }) = > {
if (networkError.statusCode === 401) { logout(); }})Copy the code
But IN my project, networkError is always a string… Failed to fetch, failed to receive the statusCode, so I went to find the associated issue, there is a real problem, issue300, the solution given in issue is to adjust the TS type of networkError, Although I was confused about why the data was related to the type at first, I still tried it with hope and found that 😭 did not work. Since then, I have been wandering around in the issue, but I still haven’t found a solution
Check problem,
No way, can only go all the way to find the source code, look at the code, did not see what the problem, but is not. Only add breakpoints where doubt the debugger, the final check is Apollo – link – HTTP – parseAndCheckHttpResponse function in common
var parseAndCheckHttpResponse = function (operations) { return function (response) {
return (response
.text()
.then(function (bodyText) {
try {
return JSON.parse(bodyText);
}
catch (err) {
var parseError = err;
parseError.name = 'ServerParseError';
parseError.response = response;
parseError.statusCode = response.status;
parseError.bodyText = bodyText;
return Promise.reject(parseError);
}
})
.then(function (result) {
if (response.status >= 300) {
throwServerError(response, result, "Response not successful: Received status code " + response.status);
}
if (!Array.isArray(result) && ! result.hasOwnProperty('data') &&
!result.hasOwnProperty('errors')) {
throwServerError(response, result, "Server response was missing for query '" + (Array.isArray(operations)
? operations.map(function (op) { return op.operationName; })
: operations.operationName) + "'.");
}
return result;
}));
}; };
Copy the code
Can you tell what’s wrong with the code up there? Reponse.text () raises an error, where the error is a string, so that the following THEN cannot be used to determine the status.
Reponse.text ()
React-apollo fetch uses the browser’s native FETCH
fetch(url)
.then(response= > response.json())
.then(res= > {
// Process data
})
Copy the code
Json methods are used for json data types returned by the server, and.text is used for text/ XXX. Looking at a reply on StackOverflow, and the fact that I said in my previous issue that it might be the data returned by the server, made me turn my attention to the server.
First of all, 200 is ok, is 401 not text? Look for information first. No, that could be wrong. Try writing code
var http = require(" HTTP ");var server = http.createServer(function (request, response) {
console.log(request.method + ':' + request.url); response.writeHead(401, {the content-type: text/plain, 'Access - Control - Allow - Origin:' * '}); response.end('Hello world! ');
});
// Let the server listen on port 65534:
server.listen(65534);
console.log(' Server is running at HTTP:/ / 127.0.0.1:65534 / ');
Copy the code
Fetch, response.text() is ok on the Chrome console. So what’s the problem? In the server code I see res.end(); I tried adding Hello world to end, and it worked!
Text () :
The text() method of the Body mixin takes a Response stream and reads it to completion. It returns a promise that resolves with a USVString object (text). The response is always decoded using UTF-8.
Is there an error because there is no stream? At this time, I remembered a status code 204, which means no content, that is, no returned data. Then, for this request, will it also enter the catch according to the conventional writing method of fetch? The problem was really found in the issue of Fetch, and the solution is as follows:
const r = await fetch('https:... ', { method: 'POST'. });if (r.ok) {
const data = await r.json().catch((a)= > null);
// ...
}
Copy the code
Node-fecth has a similar discussion: github.com/node-fetch/… “, which means it’s not quite up to code. Uh, well… I still like 204…