Skip to content

Commit e86fe29

Browse files
committed
v1.13.1
1 parent 3ab1c06 commit e86fe29

30 files changed

+208
-150
lines changed

CHANGE_LOG.md

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
11
# Change Log
2+
3+
## Version [1.13.1](https://github.com/heliomarpm/udemy-downloader-gui/compare/v1.13.0...v1.13.1)
4+
##### Aug, 08 2024
5+
![](https://img.shields.io/github/downloads/heliomarpm/udemy-downloader-gui/v1.13.1/total)
6+
7+
8+
### Issues Fixed
9+
* Download preparer
10+
- [#198](https://github.com/heliomarpm/udemy-downloader-gui/issues/198)
11+
- [#201](https://github.com/heliomarpm/udemy-downloader-gui/issues/201)
12+
- [#206](https://github.com/heliomarpm/udemy-downloader-gui/issues/206)
13+
- [#207](https://github.com/heliomarpm/udemy-downloader-gui/issues/207)
14+
15+
* Server Unavailable - improved error messages
16+
- [#200](https://github.com/heliomarpm/udemy-downloader-gui/issues/200)
17+
- [#204](https://github.com/heliomarpm/udemy-downloader-gui/issues/204)
18+
19+
20+
----
21+
## Version [1.13.0](https://github.com/heliomarpm/udemy-downloader-gui/compare/v1.12.9...v1.13.0)
22+
##### Jul, 11 2024
23+
![](https://img.shields.io/github/downloads/heliomarpm/udemy-downloader-gui/v1.13.0/total)
24+
25+
### Fixed
26+
* download speed information
27+
28+
229
----
3-
## Version [1.12.8](https://github.com/heliomarpm/udemy-downloader-gui/compare/v1.12.7...v1.12.8)
4-
##### Aug, 22 2023
5-
![](https://img.shields.io/github/downloads/heliomarpm/udemy-downloader-gui/v1.12.8/total)
30+
## Version [1.12.9](https://github.com/heliomarpm/udemy-downloader-gui/compare/v1.12.7...v1.12.9)
31+
##### Apr, 04 2024
32+
![](https://img.shields.io/github/downloads/heliomarpm/udemy-downloader-gui/v1.12.9/total)
633

734
### Fixed
835
* download speed information
36+
* downloadError (#185)
937

1038
### Updates
1139
* GitHub Issues Templates

app/app.js

+69-57
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ async function checkUpdate(account, silent = false) {
282282
}
283283
}
284284

285-
async function checkLogin() {
285+
async function checkLogin(alertExpired = true) {
286286
if (Settings.accessToken) {
287287
try {
288288
ui.busyLogin(true);
@@ -291,6 +291,9 @@ async function checkLogin() {
291291
const userContext = await udemyService.fetchProfile(Settings.accessToken, 30000);
292292

293293
if (!userContext.header.isLoggedIn) {
294+
if (alertExpired) {
295+
showAlert(translate("Token expired"));
296+
}
294297
ui.resetToLogin();
295298
return;
296299
}
@@ -516,8 +519,8 @@ function resetCourse($course, $elMessage, autoRetry, courseData, subtitle) {
516519
} else {
517520
$course.attr("course-completed", "");
518521

519-
if ($elMessage.hasClass("download-error")) {
520-
if (autoRetry && courseData.errorCount++ < 5) {
522+
if ($elMessage.hasClass("download-error") && autoRetry && courseData) {
523+
if (courseData.errorCount++ < 5) {
521524
$course.length = 1;
522525
startDownload($course, courseData, subtitle);
523526
return;
@@ -648,7 +651,7 @@ async function fetchCourseContent(courseId, courseName, courseUrl) {
648651
showAlert(`Id: ${courseId}`, translate("Course not found"));
649652
return null;
650653
}
651-
// console.log("fetchCourseContent", response);
654+
console.log(`fetchCourseContent (${courseId})`, response);
652655

653656
const downloadType = Number(Settings.download.type);
654657
const downloadAttachments = downloadType === Settings.DownloadType.Both || downloadType === Settings.DownloadType.OnlyAttachments;
@@ -672,7 +675,7 @@ async function fetchCourseContent(courseId, courseName, courseUrl) {
672675
}
673676
chapterData = { id: item.id, name: item.title.trim(), lectures: [] };
674677
}
675-
else if (type == "quiz") {
678+
else if (type == "quiz" || type == "practice") {
676679
const srcUrl = `${courseUrl}t/${item._class}/${item.id}`;
677680

678681
chapterData.lectures.push({
@@ -765,22 +768,7 @@ async function fetchCourseContent(courseId, courseName, courseUrl) {
765768
// ui.busyBuildingCourseData(false);
766769
return courseData;
767770
} catch (error) {
768-
let msgError;
769-
const statusCode = error.response ? error.response.status : 0;
770-
switch (statusCode) {
771-
case 403:
772-
msgError = translate("You do not have permission to access this course");
773-
prompt.alert(msgError);
774-
break;
775-
case 504:
776-
msgError = "Gateway timeout";
777-
break;
778-
default:
779-
msgError = error.message;
780-
break;
781-
}
782-
appendLog(`EBUILDING_COURSE_DATA: ${error.code}(${statusCode})`, msgError);
783-
throw utils.newError("EBUILDING_COURSE_DATA", msgError);
771+
handleApiError(error, "EBUILDING_COURSE_DATA", courseName, true);
784772
}
785773
}
786774

@@ -795,10 +783,7 @@ async function fetchCourses(isSubscriber) {
795783
}
796784
})
797785
.catch(e => {
798-
const statusCode = (e.response?.status || 0).toString() + (e.code ? ` :${e.code}` : "");
799-
appendLog(`EFETCHING_COURSES: ${e.code}(${statusCode})`, e.message);
800-
//showAlert(error.message, "Fetching Courses");
801-
throw utils.newError("EFETCHING_COURSES", e.message);
786+
handleApiError(e, "EFETCHING_COURSES");
802787
})
803788
.finally(() => {
804789
ui.busyLoadCourses(false);
@@ -821,7 +806,7 @@ function loadMore(loadMoreButton) {
821806
}
822807
}).catch(e => {
823808
const statusCode = (e.response?.status || 0).toString() + (e.code ? ` :${e.code}` : "");
824-
appendLog(`loadMore_Error: (${statusCode})`, e);
809+
appendLog(`ELOADING_MORE: (${statusCode})`, e);
825810
}).finally(() => {
826811
ui.busyLoadCourses(false);
827812
});
@@ -834,8 +819,7 @@ async function search(keyword) {
834819
const courses = await udemyService.fetchSearchCourses(keyword, PAGE_SIZE, Settings.subscriber);
835820
renderCourses(courses, !!keyword);
836821
} catch (error) {
837-
const statusCode = (error.response?.status || 0).toString() + (error.code ? ` :${error.code}` : "");
838-
appendLog(`search_Error: (${statusCode})`, error);
822+
handleApiError(error, "ESEARCHING_COURSES", null, false);
839823
} finally {
840824
ui.busyLoadCourses(false);
841825
}
@@ -984,8 +968,9 @@ async function prepareDownloading($course, subtitle) {
984968

985969
console.clear();
986970

971+
let courseData = null;
987972
try {
988-
const courseData = await fetchCourseContent(courseId, courseName, courseUrl);
973+
courseData = await fetchCourseContent(courseId, courseName, courseUrl);
989974
if (!courseData) {
990975
ui.showProgress($course, false);
991976
return;
@@ -1006,22 +991,11 @@ async function prepareDownloading($course, subtitle) {
1006991
}
1007992

1008993
} catch (error) {
1009-
let msgError;
1010-
const statusCode = error.response?.status || 0;
1011-
switch (statusCode) {
1012-
case 403:
1013-
msgError = translate("You do not have permission to access this course") + `\nId: ${courseId}`;
1014-
showAlert(msgError, "Download Error");
1015-
break;
1016-
case 504:
1017-
msgError = "Gateway timeout";
1018-
break;
1019-
default:
1020-
msgError = error;
1021-
}
1022-
const errorCode = error.code ? ` :${error.code}` : "";
1023-
appendLog(`EPREPARE_DOWNLOADING: (${statusCode}${errorCode})`, msgError);
994+
const errorName = error.name === "EASK_FOR_SUBTITLE" ? error.name : "EPREPARE_DOWNLOADING";
995+
handleApiError(error, errorName, null, false);
1024996
ui.busyOff();
997+
998+
resetCourse($course, $course.find(".download-error"), Settings.download.autoRetry, courseData, subtitle);
1025999
}
10261000
}
10271001

@@ -1173,9 +1147,7 @@ function startDownload($course, courseData, subTitle = "") {
11731147
fs.mkdirSync(seqName.fullPath, { recursive: true });
11741148
downloadLecture(chapterIndex, lectureIndex, countLectures, seqName.name);
11751149
} catch (error) {
1176-
appendLog("downloadChapter_Error:", error);
1177-
dialog.showErrorBox("downloadChapter_Error", error.message);
1178-
1150+
handleApiError(error, "EDOWNLOADING_CHAPTER", null, false);
11791151
resetCourse($course, $course.find(".download-error"), false, courseData);
11801152
}
11811153
}
@@ -1266,9 +1238,7 @@ function startDownload($course, courseData, subTitle = "") {
12661238
}).then(() => {
12671239
resetCourse($course, $course.find(".download-error"), Settings.download.autoRetry, courseData, subtitle);
12681240
}).catch((error) => {
1269-
const statusCode = error.response?.status || 0;
1270-
const errorCode = error.code ? ` :${error.code}` : "";
1271-
appendLog(`downloadLecture_Error: (${statusCode}${errorCode})`, error);
1241+
handleApiError(error, "EDL_DOWNLOADING_LECTURE", courseData.name, false);
12721242

12731243
try {
12741244
if (statusCode == 401 || statusCode == 403) {
@@ -1296,7 +1266,7 @@ function startDownload($course, courseData, subTitle = "") {
12961266
if (hasDRMProtection(dl)) {
12971267
dl.emit("end");
12981268
} else {
1299-
appendLog("errorDownload", dl.error.message);
1269+
appendLog("DL_ONERROR", dl.error.message);
13001270
}
13011271
});
13021272

@@ -1779,11 +1749,13 @@ function clearBagdeLoggers() {
17791749
* @param {string} title - The title of the log entry.
17801750
* @param {string|Error|object} error - The error message or Error object.
17811751
*/
1782-
function appendLog(title, error) {
1783-
const description = error instanceof Error
1784-
? error.message
1752+
function appendLog(title, error, additionalDescription = "") {
1753+
let description = error instanceof Error
1754+
? error.message //`${error.message}\n ${error.stack}`
17851755
: (typeof error == "object" ? JSON.stringify(error) : error);
17861756

1757+
description += additionalDescription !== "" ? "\n\n" + additionalDescription : "";
1758+
17871759
// item added to list to display
17881760
$(".ui.logger.section .ui.list").prepend(
17891761
`<div class="item">
@@ -1810,6 +1782,7 @@ function appendLog(title, error) {
18101782

18111783
if (error instanceof Error) {
18121784
console.error(`[${title}] ${error.message}\n ${error.stack}`);
1785+
captureException(error);
18131786
} else {
18141787
console.warn(`[${title}] ${description}`);
18151788
}
@@ -1846,6 +1819,45 @@ function saveLogFile() {
18461819
});
18471820
}
18481821

1822+
function handleApiError(error, errorName, courseName = null, triggerThrow = true) {
1823+
error.name = errorName;
1824+
error.code = error.code || "";
1825+
1826+
const statusCode = error.response?.status || 0;
1827+
switch (statusCode) {
1828+
case 403:
1829+
error.message = translate("You do not have permission to access this course");
1830+
// prompt.alert(msgError);
1831+
showAlertError(error.message, errorName);
1832+
break;
1833+
case 503:
1834+
error.message = translate("Service is temporarily unavailable. Please wait a few minutes and try again.");
1835+
showAlertError(error.message, errorName);
1836+
break;
1837+
case 504:
1838+
error.message = "Gateway timeout";
1839+
showAlertError(error.message, errorName);
1840+
break;
1841+
default:
1842+
break;
1843+
}
1844+
1845+
if (courseName)
1846+
error.message += `\n\n course: ${courseName}`;
1847+
1848+
appendLog(`${errorName}: ${error.code}(${statusCode})`, error);
1849+
1850+
if (triggerThrow) {
1851+
// throw utils.newError(errorName, error.message);
1852+
throw error;
1853+
}
1854+
}
1855+
1856+
function showAlertError(message, title = "") {
1857+
title = title ? `.:: ${title} ::.` : ".:: Error ::.";
1858+
dialog.showErrorBox(title, message);
1859+
}
1860+
18491861
function showAlert(message, title = "") {
18501862
if (title) title = `.:: ${title} ::.\n\r`;
18511863
dialogs.alert(`${title}${message}`);
@@ -1856,14 +1868,14 @@ function captureException(exception) {
18561868
}
18571869

18581870
process.on("uncaughtException", (error) => {
1859-
appendLog("uncaughtException", error);
1871+
appendLog("EPROCESS_UNCAUGHT_EXCEPTION", error);
18601872
captureException(error);
18611873
});
18621874

18631875
process.on("unhandledRejection", (error) => {
1864-
appendLog("unhandledRejection", error);
1876+
appendLog("EPROCESS_UNHANDLED_REJECTION", error);
18651877
captureException(error);
18661878
});
18671879

18681880
// console.table(getAllDownloadsHistory());
1869-
checkLogin();
1881+
checkLogin(false);

0 commit comments

Comments
 (0)