not-an-aardvark / snoowrap

A JavaScript wrapper for the reddit API
MIT License
1.02k stars 127 forks source link

Implicit calls under the hood, not sure where UnhandledPromiseRejectionWarning #153

Open pthieu opened 6 years ago

pthieu commented 6 years ago

I'm getting this unhandled error:

(node:89515) UnhandledPromiseRejectionWarning: Error: [deleted]
    at RedditUser.get _uri [as _uri] (/Users/pthieu/www/asb-scraper-service/node_modules/snoowrap/dist/objects/RedditUser.js:31:13)
    at RedditUser.fetch (/Users/pthieu/www/asb-scraper-service/node_modules/snoowrap/dist/objects/RedditContent.js:85:67)
    at Object.get (/Users/pthieu/www/asb-scraper-service/node_modules/snoowrap/dist/objects/RedditContent.js:52:113)
    at Proxy.toString (<anonymous>)
    at objectToString (/Users/pthieu/www/asb-scraper-service/node_modules/objection/lib/utils/clone.js:1767:33)
    at baseGetTag (/Users/pthieu/www/asb-scraper-service/node_modules/objection/lib/utils/clone.js:1177:9)
...

I'm actually not sure where this is coming from as all I'm doing are r.getSubmission's and submission.fetch().comments's

I've put try-catch blocks on any snoowrap call so I'm thinking there must be something happening like a heartbeat or something under the hood.

This error also makes me think something is happening under the hood as I'm only making 5 api calls every 30 seconds, which comes out to be 10 a minute, 100 per 10 minutes which is under reddit's API limits.

Unhandled rejection Error: snoowrap refused to continue because reddit's ratelimit was exceeded. For more information about reddit's ratelimit, please consult reddit's API rules at https://github.com/reddit/reddit/wiki/API.
    at snoowrap._awaitRatelimit (/Users/pthieu/www/asb-scraper-service/node_modules/snoowrap/dist/request_handler.js:155:11)
    at /Users/pthieu/www/asb-scraper-service/node_modules/snoowrap/dist/request_handler.js:81:18
    at runCallback (timers.js:696:18)
not-an-aardvark commented 6 years ago

Hi,

Could you share the code that you're using? It's hard to tell what's going on without any code. My best guess is that you are trying to get information about a user whose account has been deleted.

pthieu commented 6 years ago

my core code is something like this:

const Snoowrap = require('snoowrap');

const config = require('./config')

const redditOpts = {
  userAgent: config.REDDIT_USER_AGENT,
  clientId: config.REDDIT_CLIENT_ID,
  clientSecret: config.REDDIT_CLIENT_SECRET,
  refreshToken: config.REDDIT_REFRESH_TOKEN,
};

const r = new Snoowrap(redditOpts);

async const main() {
  const results = [];
  const comments = [];

  const redditId = post.reddit_id;
  const submission = await r.getSubmission(redditId);

  results.push(submission)
  const commentsData = await submission.fetch().comments
  const comments = comments.concat(...commentsData);
}

I think submission.fetch() might be fetching everything that's in the Submission Listing? including user.

Anyway, I swapped all these calls with the browser .json requests since they're all GET requests and the rate-limit errors went away

ZeroTricks commented 5 years ago

These errors seem to happen when the author of a submission is deleted. This is not immediately clear as the error being thrown is just that, the invalid username '[deleted]'.

r.getSubmission('9ka5gm').author.fetch().then(console.log); // unhandled rejection (Error: [deleted])
r.getSubmission('9ka5gm').author.then(console.log); // RedditUser { name: '[deleted]' } (no error, no unhandled rejection)
r.getSubmission('9ka5gm').author.then(a => console.log(a.name)); //[deleted] (no error, no unhandled rejection)
r.getSubmission('9ka5gm').author.then(a => console.log(a.is_suspended)); // unhandled rejection (Error: [deleted])
r.getUser('[deleted]').fetch().then(console.log); // (Error: [deleted]) (thrown error, instead of unhandled rejection)
r.getUser('deleted').fetch().then(console.log); // RedditUser { is_suspended: true, name: 'deleted' } (real user, no error)

Putting the right .catch() 'es in the examples above is easy but i needed a workaround for some business logic i couldn't change, so i ended up with something like:

if(post.author.name == '[deleted]'){
  console.log('Avoiding snoowrap failures by changing crossposted author [deleted] to deleted');
  post.author.name = 'deleted';
}
business logic doing stuff with post;

Authors can also be in embedded crossposts, so also check

if(post.crosspost_parent_list && post.crosspost_parent_list[0].author.name == '[deleted]'){
  console.log('Avoiding snoowrap failures by changing crossposted author [deleted] to deleted');
  post.crosspost_parent_list[0].author.name = 'deleted';
}

Not sure if there's more places where there can be a [deleted] author.

Venefilyn commented 4 years ago

I've not been able to reproduce this as I can't figure out how this could occur in the code-snippet