discourse: fix fetch failure on 410 (#1366)

When a post or topic is deleted, Discourse fetch will give status 410.
As with 404 and 403, we should just ignore the post and move on.

I took the opportunity to slightly refactor the fetch error handling
while I was there.

Test plan: Previously, doing a load on the SourceCred discourse instance
would fail due to a deleted topic. Now, it doesn't.
This commit is contained in:
Dandelion Mané 2019-09-10 19:13:13 +02:00 committed by GitHub
parent aecd2864bf
commit dcf4010ff0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 28 deletions

View File

@ -150,8 +150,7 @@ export class Fetcher implements Discourse {
async latestTopicId(): Promise<TopicId> { async latestTopicId(): Promise<TopicId> {
const response = await this._fetch("/latest.json?order=created"); const response = await this._fetch("/latest.json?order=created");
failFor404(response); failIfMissing(response);
failFor403(response);
failForNotOk(response); failForNotOk(response);
const json = await response.json(); const json = await response.json();
if (json.topic_list.topics.length === 0) { if (json.topic_list.topics.length === 0) {
@ -162,8 +161,7 @@ export class Fetcher implements Discourse {
async latestPosts(): Promise<Post[]> { async latestPosts(): Promise<Post[]> {
const response = await this._fetch("/posts.json"); const response = await this._fetch("/posts.json");
failFor404(response); failIfMissing(response);
failFor403(response);
failForNotOk(response); failForNotOk(response);
const json = await response.json(); const json = await response.json();
return json.latest_posts.map(parsePost); return json.latest_posts.map(parsePost);
@ -171,18 +169,10 @@ export class Fetcher implements Discourse {
async topicWithPosts(id: TopicId): Promise<TopicWithPosts | null> { async topicWithPosts(id: TopicId): Promise<TopicWithPosts | null> {
const response = await this._fetch(`/t/${id}.json`); const response = await this._fetch(`/t/${id}.json`);
if (response.status === 404) { const {status} = response;
// Not sure why this happens, but a topic can sometimes 404. if (status === 403 || status === 404 || status === 410) {
// We should just consider it unreachable. // The topic is hidden, deleted, or otherwise missing.
// Here is an example: https://discourse.sourcecred.io/t/116 // Example of a 404 topic: https://discourse.sourcecred.io/t/116
return null;
}
if (response.status === 403) {
// Probably this topic is hidden or deleted.
// Just consider it unreachable.
// If the issue is that the user provided bad keys, then
// they will get a more helpful error when they try to get the latest
// topic id.
return null; return null;
} }
failForNotOk(response); failForNotOk(response);
@ -199,12 +189,9 @@ export class Fetcher implements Discourse {
async post(id: PostId): Promise<Post | null> { async post(id: PostId): Promise<Post | null> {
const response = await this._fetch(`/posts/${id}.json`); const response = await this._fetch(`/posts/${id}.json`);
if (response.status === 404) { const {status} = response;
// Since topics can 404, I assume posts can too. if (status === 403 || status === 404 || status === 410) {
return null; // The post is hidden, deleted, or otherwise missing.
}
if (response.status === 403) {
// Probably this post is hidden or deleted.
return null; return null;
} }
failForNotOk(response); failForNotOk(response);
@ -216,25 +203,25 @@ export class Fetcher implements Discourse {
const response = await this._fetch( const response = await this._fetch(
`/user_actions.json?username=${username}&filter=1&offset=${offset}` `/user_actions.json?username=${username}&filter=1&offset=${offset}`
); );
failFor404(response); failIfMissing(response);
failFor403(response);
failForNotOk(response); failForNotOk(response);
const json = await response.json(); const json = await response.json();
return json.user_actions.map(parseLike); return json.user_actions.map(parseLike);
} }
} }
function failFor404(response: Response) { function failIfMissing(response: Response) {
if (response.status === 404) { if (response.status === 404) {
throw new Error(`404 Not Found on: ${response.url}; maybe bad serverUrl?`); throw new Error(`404 Not Found on: ${response.url}; maybe bad serverUrl?`);
} }
}
function failFor403(response: Response) {
if (response.status === 403) { if (response.status === 403) {
throw new Error(`403 Forbidden: bad API username or key?`); throw new Error(`403 Forbidden: bad API username or key?`);
} }
if (response.status === 410) {
throw new Error(`410 Gone`);
}
} }
function failForNotOk(response: Response) { function failForNotOk(response: Response) {
if (!response.ok) { if (!response.ok) {
throw new Error(`not OK status ${response.status} on ${response.url}`); throw new Error(`not OK status ${response.status} on ${response.url}`);