{ "version": 3, "sources": ["../../../lib/crashlogger.ts"], "sourcesContent": ["/**\r\n * Crash logger\r\n * Pokemon Showdown - http://pokemonshowdown.com/\r\n *\r\n * Logs crashes, sends an e-mail notification if you've set up\r\n * config.js to do that.\r\n *\r\n * @license MIT\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\nconst CRASH_EMAIL_THROTTLE = 5 * 60 * 1000; // 5 minutes\r\n\r\nconst logPath = path.resolve(\r\n\t// not sure why this is necessary, but in Windows testing it was\r\n\t__dirname, '../', __dirname.includes(`${path.sep}dist${path.sep}`) ? '..' : '', 'logs/errors.txt'\r\n);\r\nlet lastCrashLog = 0;\r\nlet transport: any;\r\n\r\n/**\r\n * Logs when a crash happens to console, then e-mails those who are configured\r\n * to receive them.\r\n */\r\nexport function crashlogger(\r\n\terror: unknown,\r\n\tdescription: string,\r\n\tdata: AnyObject | null = null,\r\n\temailConfig: AnyObject | null = null,\r\n): string | null {\r\n\tconst datenow = Date.now();\r\n\r\n\tlet stack = (typeof error === 'string' ? error : (error as Error)?.stack) || '';\r\n\tif (data) {\r\n\t\tstack += `\\n\\nAdditional information:\\n`;\r\n\t\tfor (const k in data) {\r\n\t\t\tstack += ` ${k} = ${data[k]}\\n`;\r\n\t\t}\r\n\t}\r\n\r\n\tconsole.error(`\\nCRASH: ${stack}\\n`);\r\n\tconst out = fs.createWriteStream(logPath, {flags: 'a'});\r\n\tout.on('open', () => {\r\n\t\tout.write(`\\n${stack}\\n`);\r\n\t\tout.end();\r\n\t}).on('error', (err: Error) => {\r\n\t\tconsole.error(`\\nSUBCRASH: ${err.stack}\\n`);\r\n\t});\r\n\r\n\tconst emailOpts = emailConfig || global.Config?.crashguardemail;\r\n\tif (emailOpts && ((datenow - lastCrashLog) > CRASH_EMAIL_THROTTLE)) {\r\n\t\tlastCrashLog = datenow;\r\n\r\n\t\tif (!transport) {\r\n\t\t\ttry {\r\n\t\t\t\trequire.resolve('nodemailer');\r\n\t\t\t} catch {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t'nodemailer is not installed, but it is required if Config.crashguardemail is configured! ' +\r\n\t\t\t\t\t'Run npm install --no-save nodemailer and restart the server.'\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlet text = `${description} crashed `;\r\n\t\tif (transport) {\r\n\t\t\ttext += `again with this stack trace:\\n${stack}`;\r\n\t\t} else {\r\n\t\t\ttry {\r\n\t\t\t\ttransport = require('nodemailer').createTransport(emailOpts.options);\r\n\t\t\t} catch {\r\n\t\t\t\tthrow new Error(\"Failed to start nodemailer; are you sure you've configured Config.crashguardemail correctly?\");\r\n\t\t\t}\r\n\r\n\t\t\ttext += `with this stack trace:\\n${stack}`;\r\n\t\t}\r\n\r\n\t\ttransport.sendMail({\r\n\t\t\tfrom: emailOpts.from,\r\n\t\t\tto: emailOpts.to,\r\n\t\t\tsubject: emailOpts.subject,\r\n\t\t\ttext,\r\n\t\t}, (err: Error | null) => {\r\n\t\t\tif (err) console.error(`Error sending email: ${err}`);\r\n\t\t});\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n"], "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,SAAoB;AACpB,WAAsB;AAXtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,uBAAuB,IAAI,KAAK;AAEtC,MAAM,UAAU,KAAK;AAAA;AAAA,EAEpB;AAAA,EAAW;AAAA,EAAO,UAAU,SAAS,GAAG,KAAK,UAAU,KAAK,KAAK,IAAI,OAAO;AAAA,EAAI;AACjF;AACA,IAAI,eAAe;AACnB,IAAI;AAMG,SAAS,YACf,OACA,aACA,OAAyB,MACzB,cAAgC,MAChB;AAChB,QAAM,UAAU,KAAK,IAAI;AAEzB,MAAI,SAAS,OAAO,UAAU,WAAW,QAAS,OAAiB,UAAU;AAC7E,MAAI,MAAM;AACT,aAAS;AAAA;AAAA;AAAA;AACT,eAAW,KAAK,MAAM;AACrB,eAAS,KAAK,OAAO,KAAK,CAAC;AAAA;AAAA,IAC5B;AAAA,EACD;AAEA,UAAQ,MAAM;AAAA,SAAY;AAAA,CAAS;AACnC,QAAM,MAAM,GAAG,kBAAkB,SAAS,EAAC,OAAO,IAAG,CAAC;AACtD,MAAI,GAAG,QAAQ,MAAM;AACpB,QAAI,MAAM;AAAA,EAAK;AAAA,CAAS;AACxB,QAAI,IAAI;AAAA,EACT,CAAC,EAAE,GAAG,SAAS,CAAC,QAAe;AAC9B,YAAQ,MAAM;AAAA,YAAe,IAAI;AAAA,CAAS;AAAA,EAC3C,CAAC;AAED,QAAM,YAAY,eAAe,OAAO,QAAQ;AAChD,MAAI,aAAe,UAAU,eAAgB,sBAAuB;AACnE,mBAAe;AAEf,QAAI,CAAC,WAAW;AACf,UAAI;AACH,wBAAgB,YAAY;AAAA,MAC7B,QAAE;AACD,cAAM,IAAI;AAAA,UACT;AAAA,QAED;AAAA,MACD;AAAA,IACD;AAEA,QAAI,OAAO,GAAG;AACd,QAAI,WAAW;AACd,cAAQ;AAAA,EAAiC;AAAA,IAC1C,OAAO;AACN,UAAI;AACH,oBAAY,QAAQ,YAAY,EAAE,gBAAgB,UAAU,OAAO;AAAA,MACpE,QAAE;AACD,cAAM,IAAI,MAAM,8FAA8F;AAAA,MAC/G;AAEA,cAAQ;AAAA,EAA2B;AAAA,IACpC;AAEA,cAAU,SAAS;AAAA,MAClB,MAAM,UAAU;AAAA,MAChB,IAAI,UAAU;AAAA,MACd,SAAS,UAAU;AAAA,MACnB;AAAA,IACD,GAAG,CAAC,QAAsB;AACzB,UAAI;AAAK,gBAAQ,MAAM,wBAAwB,KAAK;AAAA,IACrD,CAAC;AAAA,EACF;AAEA,SAAO;AACR;", "names": [] }