我有一个用Snoowrap和Snoostorm用Nodejs编写的reddit机器人,并已部署到Heroku。 我的日志不断提示该错误:
2020-03-13T06:02:53.784219+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: RequestError: Error: ESOCKETTIMEDOUT
2020-03-13T06:02:53.784229+00:00 app[web.1]: at new RequestError (/app/node_modules/request-promise-core/lib/errors.js:14:15)
2020-03-13T06:02:53.784230+00:00 app[web.1]: at Request.plumbing.callback (/app/node_modules/request-promise-core/lib/plumbing.js:87:29)
2020-03-13T06:02:53.784231+00:00 app[web.1]: at Request.RP$callback [as _callback] (/app/node_modules/request-promise-core/lib/plumbing.js:46:31)
2020-03-13T06:02:53.784231+00:00 app[web.1]: at self.callback (/app/node_modules/request/request.js:185:22)
2020-03-13T06:02:53.784234+00:00 app[web.1]: at Request.emit (events.js:311:20)
2020-03-13T06:02:53.784234+00:00 app[web.1]: at ClientRequest.<anonymous> (/app/node_modules/request/request.js:819:16)
2020-03-13T06:02:53.784235+00:00 app[web.1]: at Object.onceWrapper (events.js:417:28)
2020-03-13T06:02:53.784235+00:00 app[web.1]: at ClientRequest.emit (events.js:311:20)
2020-03-13T06:02:53.784236+00:00 app[web.1]: at TLSSocket.emitRequestTimeout (_http_client.js:714:9)
2020-03-13T06:02:53.784237+00:00 app[web.1]: at Object.onceWrapper (events.js:417:28)
2020-03-13T06:02:53.784237+00:00 app[web.1]: at TLSSocket.emit (events.js:311:20)
2020-03-13T06:02:53.784237+00:00 app[web.1]: at TLSSocket.Socket._onTimeout (net.js:478:8)
2020-03-13T06:02:53.784238+00:00 app[web.1]: at listOnTimeout (internal/timers.js:549:17)
2020-03-13T06:02:53.784238+00:00 app[web.1]: at processTimers (internal/timers.js:492:7)
2020-03-13T06:02:53.784281+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)`
这是我的app.js文件:
require('dotenv').config();
const MyUtil = require("./myutil.js")
const { CommentStream, SubmissionStream, ModMailStream, InboxStream } = require("snoostorm");
const Snoowrap = require('snoowrap');
const Snoostorm = require('snoostorm');
const WatchJS = require("melanke-watchjs")
const r = new Snoowrap({
userAgent: 'abcde',
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refreshToken: process.env.REFRESH_TOKEN
});
const BOT_START = Date.now() / 1000;
var webController;
function initializeBot(controller){
configReddit();
watchRateLimit();
initCommentStream();
initPostStream();
initInboxStream();
initModMailStream();
webController = controller;
return module.exports
}
function configReddit(){
r.config({continueAfterRatelimitError: true});
console.info("Finished Reddit configuration.")
}
function watchRateLimit(){
//WATCH JS
// var watch = WatchJS.watch;
// var unwatch = WatchJS.unwatch;
// var callWatchers = WatchJS.callWatchers;
WatchJS.watch(r, "ratelimitRemaining",
() => {
if(r.ratelimitRemaining < 50){
console.warn("Rate limit remaining:" +r.ratelimitRemaining);
}
if(webController){
webController.broadcast(r.ratelimitRemaining);
}
});
}
function initCommentStream(){
console.info("Trying to establish comment stream!");
var streamOpts;
try {
streamOpts = JSON.parse(process.env.COMMENT_STREAM_OPTION);
if(!streamOpts || !streamOpts.receiving){
console.info("Comment Stream was disabled, enable through the environment variable.")
return;
}
} catch (error) {
console.log(error);
console.info("COMMENT_STREAM_OPTION unavailable/wrong format.");
return;
}
const comments = new CommentStream(r, streamOpts);
comments.on("item", comment => {
if(comment.created_utc < BOT_START) return;
if(comment.body.toLowerCase().includes("!resolved")){
console.log("New resolved comment!: "+comment.link_id.substring(3))
let flair = {flair_template_id:MyUtil.FLAIR_ID.RESOLVED}
let sub = r.getSubmission(comment.link_id.toString().substring(3));
let reply = ""; //TODO
sub.selectFlair(flair).then(sub.reply())
}
})
console.info("Comment Stream established.");
}
function initPostStream(){
console.info("Trying to establish post stream!");
var streamOpts
try {
streamOpts = JSON.parse(process.env.POST_STREAM_OPTION);
if(!streamOpts || !streamOpts.receiving){
console.info("Post Stream was disabled, enable through the environment variable.")
return;
}
} catch (error) {
console.log(error)
console.info("POST_STREAM_OPTION unavailable/wrong format.");
return;
}
const posts = new Snoostorm.SubmissionStream(r, streamOpts);
//*Listen for items (posts)
posts.on("item", post =>{
if(post.created_utc < BOT_START) return;
console.log("New POST");
console.log(post.body);
notifyNewPost("/u/abcde", post)
//TODO
})
console.info("Post Stream established!");
}
function initInboxStream(){
//TODO
}
function initModMailStream(){
//TODO
}
async function notifyNewPost(peopleList, post){
if(!post._hasFetched){
try {
post = await post.fetch();
} catch (error) {
console.log("Error at notifyNewPost")
console.log(error);
return
}
}
var sendFunction = function(people, post){
r.composeMessage({
to:people,
subject:"New post in r/GoogleAppsScript",
text:`There's a new post in r/GoogleAppsScript:
[${post.title}](${post.url}) posted by ${post.author.name}
`
}).then(()=>{console.log(`New post notification sent to ${people}.`)})
.catch((err)=>{console.log("Error on sending noti to abcde:\n"+err)});
}
if(typeof peopleList == "string"){
sendFunction(peopleList, post);
}else{
for (const people of peopleList) {
sendFunction(people, post);
}
}
}
module.exports={
initializeBot,
r
}
这是web.js:
const controller = {};
var express = require('express');
var app = express();
const wakeDyno = require("woke-dyno");
const bot = require("./app").initializeBot(controller);
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/html/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(port, ()=>{
wakeDyno("https://gas-lighter-bot.herokuapp.com/").start();
console.log('listening on *:'+port);
});
controller.broadcast = (msg) => {
io.emit("ratelimitChanged",msg);
};
奇怪的是,日志没有告诉我错误源于我的代码,所以我有点头绪。 我已经在计算机上运行了几个小时,但是当部署到Heroku时,它在大约1分钟后引发了此错误...。
请帮助:(
编辑:这是错误对象,对我没有帮助,但是也许它将帮助您解决这个问题:(
{
name: 'RequestError',
message: 'Error: ESOCKETTIMEDOUT',
cause: Error: ESOCKETTIMEDOUT
at ClientRequest.<anonymous> (/app/node_modules/request/request.js:816:19)
at Object.onceWrapper (events.js:417:28)
at ClientRequest.emit (events.js:311:20)
at TLSSocket.emitRequestTimeout (_http_client.js:714:9)
at Object.onceWrapper (events.js:417:28)
at TLSSocket.emit (events.js:311:20)
at TLSSocket.Socket._onTimeout (net.js:478:8)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
code: 'ESOCKETTIMEDOUT',
connect: false
},
error: Error: ESOCKETTIMEDOUT
at ClientRequest.<anonymous> (/app/node_modules/request/request.js:816:19)
at Object.onceWrapper (events.js:417:28)
at ClientRequest.emit (events.js:311:20)
at TLSSocket.emitRequestTimeout (_http_client.js:714:9)
at Object.onceWrapper (events.js:417:28)
at TLSSocket.emit (events.js:311:20)
at TLSSocket.Socket._onTimeout (net.js:478:8)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
code: 'ESOCKETTIMEDOUT',
connect: false
},
options: {
gzip: true,
json: true,
headers: { 'user-agent': 'myuseragent' },
baseUrl: 'https://oauth.reddit.com',
qs: { raw_json: 1 },
auth: { bearer: 'myrefreshtoken' },
resolveWithFullResponse: true,
timeout: 5000,
transform: [Function: transform],
uri: 'comments/fhxl4r',
method: 'GET',
callback: [Function: RP$callback],
simple: true,
transform2xxOnly: false
},
response: undefined
}