Skip to content

Commit

Permalink
Added fatal exceptions handling
Browse files Browse the repository at this point in the history
  • Loading branch information
loumadev committed Sep 15, 2021
1 parent f744021 commit 161492f
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 23 deletions.
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const {
EdupageError,
APIError,
MessageError,
AttachmentError
AttachmentError,
FatalError
} = require("./src/exceptions");

module.exports = {
Expand Down Expand Up @@ -73,5 +74,6 @@ module.exports = {
EdupageError,
APIError,
MessageError,
AttachmentError
AttachmentError,
FatalError
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "edupage-api",
"version": "0.7.6",
"version": "0.7.7",
"description": "Simple node.js package to manage your EduPage account.",
"main": "index.js",
"scripts": {
Expand Down
5 changes: 3 additions & 2 deletions src/ASC.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const debug = require("debug")("edupage:log");
const error = require("debug")("edupage:error");
const RawData = require("../lib/RawData");
const Edupage = require("./Edupage");
const {FatalError, ParseError} = require("./exceptions");

debug.log = console.log.bind(console);

Expand Down Expand Up @@ -97,15 +98,15 @@ class ASC extends RawData {
const data = {};
const matches = [...html.matchAll(/ASC\.([a-zA-Z0-9_$]+)\s?=\s?([\s\S]+?);/g)];

if(!matches.length) error(`Failed to parse ASC data from html`, matches);
if(!matches.length) return FatalError.throw(new ParseError("Failed to parse ASC data from html"), {html});

for(const [match, key, value] of matches) {
if(value.startsWith("function")) continue;

try {
data[key] = JSON.parse(value);
} catch(e) {
error(`Failed to parse JSON from ASC html`, match);
return FatalError.throw(new ParseError("Failed to parse JSON from ASC html"), {html, matches, match, key, value, e});
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/Edupage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const RawData = require("../lib/RawData");
const Subject = require("./Subject");
const Period = require("./Period");
const ASC = require("./ASC");
const {LoginError, EdupageError, AttachmentError, APIError} = require("./exceptions");
const {LoginError, EdupageError, AttachmentError, APIError, FatalError, ParseError} = require("./exceptions");
const Timetable = require("./Timetable");
const Message = require("./Message");
const Plan = require("./Plan");
Expand Down Expand Up @@ -706,22 +706,22 @@ class Edupage extends RawData {
};

const match = (html.match(/\.userhome\((.+?)\);$/m) || "")[1];
if(!match) return FatalError.throw(new ParseError("Failed to parse Edupage data from html"), {html});

try {
data = {...JSON.parse(match)};
} catch(e) {
if(match) error(`Failed to parse JSON from Edupage html`);
else error(`Failed to parse Edupage html`);
return FatalError.throw(new ParseError("Failed to parse JSON from Edupage html"), {html, match, e});
}

//Parse additional edubar data
const match2 = (html.match(/edubar\(([\s\S]*?)\);/) || "")[1];
if(!match2) return FatalError.throw(new ParseError("Failed to parse edubar data from html"), {html});

try {
data._edubar = JSON.parse(match2) || {};
} catch(e) {
if(match) error(`Failed to parse edubar data from html`);
error(`Failed to parse JSON from edubar html`, match2);
return FatalError.throw(new ParseError("Failed to parse JSON from edubar html"), {html, match2, e});
}

return data;
Expand Down
13 changes: 7 additions & 6 deletions src/Grade.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Season = require("./Season");
const Student = require("./Student");
const Subject = require("./Subject");
const Teacher = require("./Teacher");
const {FatalError, ParseError} = require("./exceptions");

debug.log = console.log.bind(console);

Expand Down Expand Up @@ -239,22 +240,22 @@ class Grade extends RawData {
const _settings = (html.match(/initZnamkovanieSettings\(([\s\S]*?)\);/) || "")[1];
const _data = (html.match(/znamkyStudentViewer\(([\s\S]*?)\);/) || "")[1];

if(!_settings) error(`[Grade-parser] Failed to parse settings from html`, _settings);
if(!_data) error(`[Grade-parser] Failed to parse data from html`, _data);
let settings = {};
let data = {};

var settings = {};
var data = {};
if(!_settings) return FatalError.throw(new ParseError("Failed to parse grade settings from html"), {html});
if(!_data) return FatalError.throw(new ParseError("Failed to parse grade data from html"), {html});

try {
settings = JSON.parse(_settings);
} catch(e) {
error(`[Grade-parser] Failed to parse settings as JSON`, _settings);
return FatalError.throw(new ParseError("Failed to parse grade settings as JSON"), {html, _settings});
}

try {
data = JSON.parse(_data);
} catch(e) {
error(`[Grade-parser] Failed to parse data as JSON`, _data);
return FatalError.throw(new ParseError("Failed to parse grade data as JSON"), {html, _data});
}

return {settings, data};
Expand Down
9 changes: 3 additions & 6 deletions src/Timetable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const debug = require("debug")("edupage:log");
const error = require("debug")("edupage:error");
const RawData = require("../lib/RawData");
const Edupage = require("./Edupage");
const {FatalError, ParseError} = require("./exceptions");
const Lesson = require("./Lesson");

debug.log = console.log.bind(console);
Expand Down Expand Up @@ -66,16 +67,12 @@ class Timetable extends RawData {
static parse(html) {
const match = html.match(/classbook\.fill\([\s\S]*?,\s?([\s\S]+?)(?:,\s?\[[\s\S]*?\])?\);/mi);

if(!match || !match[1]) {
error(`Failed to parse timetable data from html`, match);
return {};
}
if(!match || !match[1]) return FatalError.throw(new ParseError("Failed to parse timetable data from html"), {html, match});

try {
return JSON.parse(match[1]);
} catch(e) {
error(`Failed to parse JSON from timetable html`, match[1]);
return {};
return FatalError.throw(new ParseError("Failed to parse JSON from timetable html"), {html, match});
}
}
}
Expand Down
58 changes: 57 additions & 1 deletion src/exceptions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
const fs = require("fs");
const path = require("path");

/**
* @typedef {import("../lib/RawData").RawDataObject} RawDataObject
*/

class LoginError extends Error {
constructor(message) {
super(message);
Expand Down Expand Up @@ -40,11 +47,60 @@ class AttachmentError extends Error {
}
}

class FatalError extends Error {
/**
* @static
* @param {Error} error
* @param {RawDataObject} data
* @returns {any}
* @memberof FatalError
*/
static throw(error, data) {
const date = new Date();
const filename = `fatal_error_${date.toISOString().replace(/:/g, "-").replace(/\..\d*/, "")}.json`;
const dirname = path.resolve(__dirname, "../logs");
const file = path.join(dirname, filename);

//Create logs direcory and save error log
if(!fs.existsSync(dirname)) fs.mkdirSync(dirname);
fs.writeFileSync(file, JSON.stringify({error, data}, null, "\t"));

const message = `
#
# A fatal error has occurred!
#
# This is probably not your fault!
# If this often happens, please consider reporting an issue.
#
# Error thrown:
# ${error.stack.split("\n").join("\n# ")}
#
# Summary:
# Time: ${date.toString()}
# EdupageAPI version: v${require("../package.json").version}
# Node.js version: ${process.version}
# Error log: ${file}
#
# If you would like to submit a bug report, please visit:
# > https://github.com/loumadev/EdupageAPI/issues
# (Please, include this error message + error log)
#
`;
//Log error to stderr and exit process
console.error(message);
process.exitCode = 1;

//To comply jslint
return undefined;
}
}

module.exports = {
LoginError,
ParseError,
EdupageError,
APIError,
MessageError,
AttachmentError
AttachmentError,
FatalError
};

0 comments on commit 161492f

Please sign in to comment.