diff --git a/src/api/pushshift/index.js b/src/api/pushshift/index.js index 5f836d7..4a0c328 100644 --- a/src/api/pushshift/index.js +++ b/src/api/pushshift/index.js @@ -1,3 +1,5 @@ +import { fetchJson } from '../../utils' + const chunkSize = 100; const postURL = 'https://api.pushshift.io/reddit/submission/search/?ids=' const commentURL = `https://api.pushshift.io/reddit/comment/search/?size=${chunkSize}&sort=asc&fields=author,body,created_utc,id,link_id,parent_id,retrieved_on,retrieved_utc,score,subreddit&q=*&link_id=` @@ -9,18 +11,17 @@ const max = (a, b) => a > b ? a : b export const getPost = threadID => - window.fetch(`${postURL}${threadID}`) - .then(response => response.json()) + fetchJson(`${postURL}${threadID}`) .then(({ data }) => data[0]) - .catch(() => { + .catch(error => { + console.error('pushshift.getPost: ' + error) throw new Error('Could not get removed post') }) // Helper function that fetches a list of comments using a binary backoff, // and also returns the next delay which should be passed back in const fetchComments = (threadID, after, delay) => - window.fetch(`${commentURL}${threadID}&after=${after}`) - .then(response => response.json()) + fetchJson(`${commentURL}${threadID}&after=${after}`) .then(({ data }) => [ data.map(comment => ({ ...comment, @@ -30,9 +31,11 @@ const fetchComments = (threadID, after, delay) => delay ] ) - .catch(() => { - if (delay > 8000) + .catch(error => { + if (delay > 8000) { + console.error('pushshift.fetchComments: ' + error) throw new Error('Could not get removed comments'); + } return sleep(delay) .then(() => fetchComments(threadID, after, delay * 2)) }) diff --git a/src/api/reddit/auth.js b/src/api/reddit/auth.js index 8d72306..7087716 100644 --- a/src/api/reddit/auth.js +++ b/src/api/reddit/auth.js @@ -1,3 +1,5 @@ +import { fetchJson } from '../../utils' + // Change this to your own client ID: https://www.reddit.com/prefs/apps // The app NEEDS TO BE an installed app and NOT a web apps @@ -25,12 +27,15 @@ const getToken = () => { body: `grant_type=${encodeURIComponent('https://oauth.reddit.com/grants/installed_client')}&device_id=DO_NOT_TRACK_THIS_DEVICE` } - return window.fetch('https://www.reddit.com/api/v1/access_token', tokenInit) - .then(response => response.json()) + return fetchJson('https://www.reddit.com/api/v1/access_token', tokenInit) .then(response => { token = response.access_token return token }) + .catch(error => { + console.error('reddit.getToken ->') + throw error + }) } // Get header for general api calls diff --git a/src/api/reddit/index.js b/src/api/reddit/index.js index c5b66b0..4281776 100644 --- a/src/api/reddit/index.js +++ b/src/api/reddit/index.js @@ -1,32 +1,30 @@ -import { chunk, flatten } from '../../utils' +import { fetchJson, chunk, flatten } from '../../utils' import { getAuth } from './auth' -const errorHandler = () => { +const errorHandler = (error, from) => { + console.error(from + ': ' + error) throw new Error('Could not connect to Reddit') } // Return the post itself export const getPost = (subreddit, threadID) => ( getAuth() - .then(auth => window.fetch(`https://oauth.reddit.com/comments/${threadID}.json?limit=1`, auth)) - .then(response => response.json()) + .then(auth => fetchJson(`https://oauth.reddit.com/comments/${threadID}.json?limit=1`, auth)) .then(thread => thread[0].data.children[0].data) - .catch(errorHandler) + .catch(error => errorHandler(error, 'reddit.getPost')) ) //// Fetch multiple threads (via the info endpoint) //export const getThreads = threadIDs => { // return getAuth() -// .then(auth => window.fetch(`https://oauth.reddit.com/api/info?id=${threadIDs.map(id => `t3_${id}`).join()}`, auth)) -// .then(response => response.json()) +// .then(auth => fetchJson(`https://oauth.reddit.com/api/info?id=${threadIDs.map(id => `t3_${id}`).join()}`, auth)) // .then(response => response.data.children.map(threadData => threadData.data)) -// .catch(errorHandler) +// .catch(error => errorHandler(error, 'reddit.getThreads')) //} // Helper function that fetches a list of comments const fetchComments = (commentIDs, auth) => { - return window.fetch(`https://oauth.reddit.com/api/info?id=${commentIDs.map(id => `t1_${id}`).join()}`, auth) - .then(response => response.json()) + return fetchJson(`https://oauth.reddit.com/api/info?id=${commentIDs.map(id => `t1_${id}`).join()}`, auth) .then(results => results.data.children) .then(commentsData => commentsData.map(commentData => commentData.data)) } @@ -38,5 +36,5 @@ export const getComments = commentIDs => { .map(ids => fetchComments(ids, auth))) .then(flatten) )) - .catch(errorHandler) + .catch(error => errorHandler(error, 'reddit.getComments')) } diff --git a/src/api/removeddit/index.js b/src/api/removeddit/index.js index 1240c3a..a8f8176 100644 --- a/src/api/removeddit/index.js +++ b/src/api/removeddit/index.js @@ -1,3 +1,5 @@ +//import { fetchJson } from '../../utils' +// //const baseURL = 'http://unddit.com/api' // //export const getRemovedThreadIDs = (subreddit = '', page = 1) => { @@ -5,7 +7,9 @@ // subreddit = '' // } // -// return window.fetch(`${baseURL}/threads?subreddit=${subreddit}&page=${page - 1}`) -// .then(response => response.json()) -// .catch(() => { throw new Error('Could not get removed threads') }) +// return fetchJson(`${baseURL}/threads?subreddit=${subreddit}&page=${page - 1}`) +// .catch(error => { +// console.error('removeddit.getRemovedThreadIDs: ' + error) +// throw new Error('Could not get removed threads') +// }) //} diff --git a/src/utils.js b/src/utils.js index 5dceced..4a38061 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,6 +2,22 @@ import SnuOwnd from 'snuownd' const markdown = SnuOwnd.getParser() +// Fetches JSON at the given url or throws a descriptive Error +export const fetchJson = (url, init = {}) => + window.fetch(url, init) + .then(response => response.ok ? + response.json() + .catch(error => { + throw new Error((response.statusText || response.status) + ', ' + error) + }) : + response.text() + .catch(error => { + throw new Error((response.statusText || response.status) + ', ' + error) + }).then(text => { + throw new Error((response.statusText || response.status) + ': ' + text) + }) + ) + // Flatten arrays one level export const flatten = arr => arr.reduce( (accumulator, value) => accumulator.concat(value),