javascript - 当应用程序出错时,NodeJS Forever 的重启功能不起作用
问题描述
我用 NodeJS 和 Puppeteer 开发解析应用程序。它工作得很好,但有时网页没有加载,所以它给了我一个错误。所以我修复了我的代码,我只需要在错误出现时重新启动应用程序。
我发现永远可以在出现错误时重新启动应用程序。所以我用这个命令启动我的应用程序
forever start -o out.log -e err.log band.js
但即使应用程序出现一些错误,它也不会再次启动它。只是它停下来,什么也不做。
[错误信息]
(node:11032) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'replace' of null
at C:\Users\Downloads\Projects\Bander-Statistics\band.js:67:47
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:11032) 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(). (rejection id: 1)
(node:11032) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[乐队.js]
'use strict';
const fs = require('fs');
let article = fs.readFileSync("db.txt");
let lineArray = article.toString().split('\n')[0];
/* Initial Setting */
const initData = {
chromePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
userDataDir: 'C:\\Users\\AppData\\Local\\Google\\Chrome\\User Data',
bandNum: 58075840, // Parse Band Number
startNum: lineArray, // This variable will be read in db.txt first line
untilNum: 90000 // Parse Until What Number
}
const puppeteer = require('puppeteer'); // Puppeteer 모듈 Load
(async () => {
const browser = await puppeteer.launch({ // Puppeteer 모듈을 사용하지 않고 기존의 크롬 사용자 정보를 사용 (Auth 인증을 패스하기 위하여)
executablePath: initData.chromePath,
userDataDir: initData.userDataDir, // 설치시 개인 크롬 Directory로 수정하여야함
headless: true
});
const page = await browser.newPage(); // Broswer Open
await page.setViewport({ // Viewport 설정 가로의 경우 일반적으로 최대 1920, 새로의 경우 예상되는 최대 px를 지정해주면됨
width: 800,
height: 6000
});
page.on('dialog', async dialog => { // 삭제된 게시글의 경우 Band에서 Dialog를 띄우는데 이를 제거하기 위하여 필요
console.log(dialog.message());
await dialog.dismiss(); // Dialog 창 닫음
await postNumber++; // 삭제된 게시글의 경우 Dialog 창이 닫힌후에 이전 URL로 돌아가므로 postNumber 1증가 시켜줌
await page.goto(`https://band.us/band/${initData.bandNum}/post/${postNumber}`, {
waitUntil: 'networkidle0'
});
})
let postNumber = initData.startNum; // 시작되는 PostNumber * 이 부분 부터 시작 *
while (postNumber <= initData.untilNum) { // PostNumber 끝값 * 이 부분은 마지막 값 *
await page.goto(`https://band.us/band/${initData.bandNum}/post/${postNumber}`, {
waitUntil: 'networkidle0' // 페이지가 완전히 Load된후 작동
});
let [by, date] = await page.evaluate(() => {
const textNode = document.getElementsByClassName('text')[0];
const timeNode = document.getElementsByClassName('time')[0];
return [
textNode && textNode.innerText,
timeNode && timeNode.innerText,
];
});
if (!by || !date) {
// by or date is undefined
console.log(`Not working for ID: ${postNumber}`);
await page.reload()
postNumber++;
console.log('ERROR!')
// await element.screenshot({ path: `error-${postNumber}.png` });
await page.goto(`https://band.us/band/${initData.bandNum}/post/${postNumber}`, {
waitUntil: 'networkidle0'
});
}
let element = await page.$('.boardList'); // 게시글, 댓글 전체 Class
await element.screenshot({ // ScreenShot Function
path: `./image/${postNumber}-${by.replace("/","_")}-${date.replace(":","_")}.png` // 파일 저장 위치 & 파일이름 지정, replace 메소드의 경우 Windows 탐색기에서 :를 파일명으로 지원하지 않기때문
});
console.log(`${postNumber}-${by.replace("/","_")}-${date.replace(":","_")}.png`) // Console.log에서 파일 확인
let lastTriedNum = postNumber;
fs.writeFileSync("db.txt", '\ufeff' + lastTriedNum + '\n', {
encoding: 'utf8'
});
await postNumber++; // 최종 성공시 postnumber 증가
}
await browser.close(); // 종료
})();
我已经尝试过Supervisor、PM2、Forever,但它们都没有提供我想要的功能。
如果发生错误,我只需要能够重新启动整个应用程序。
解决方案
推荐阅读
- spring-data-elasticsearch - 如何使用 spring-data-elasticsearch 避免文档中的“_class”字段
- javascript - javascript 加载 javascript 然后渲染标题
- python - 如何根据索引的最大值差异创建新列?
- window - 如何使用赛普拉斯设置新窗口属性
- ios - 自定义 NavigationView 顶栏
- docker - 通过 dockerfile 更新 matomo 自定义变量
- javascript - 如何向需要密码的 api 发出 http 请求,而无需在我的 javascript 代码中写入密码?
- python - SymPy 可以简化包含具有复数基数的指数的实数表达式吗?
- c# - MassTransit 自动添加消费者
- groovy - 我如何从 Groovy 脚本运行 Oracle 函数并获取结果,返回 RECORD 类型的值