mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature-274] handle irrelevant oculus download errors
Ignore errors such as "no token" when auto download or "window closed by user" in the ui
This commit is contained in:
Generated
+63
-22
@@ -44,6 +44,7 @@
|
||||
"rxjs": "^7.8.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"semver": "^7.5.4",
|
||||
"serialize-error": "^8.1.0",
|
||||
"striptags": "^4.0.0-alpha.4",
|
||||
"tailwind-scrollbar-hide": "^1.1.7",
|
||||
"tailwindcss-scoped-groups": "^2.0.0",
|
||||
@@ -9427,6 +9428,35 @@
|
||||
"node": ">=10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/global-agent/node_modules/serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/global-agent/node_modules/type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "13.18.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz",
|
||||
@@ -16423,13 +16453,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz",
|
||||
"integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==",
|
||||
"dependencies": {
|
||||
"type-fest": "^0.13.1"
|
||||
"type-fest": "^0.20.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -16439,11 +16467,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/serialize-error/node_modules/type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -26365,6 +26391,25 @@
|
||||
"roarr": "^2.15.3",
|
||||
"semver": "^7.3.2",
|
||||
"serialize-error": "^7.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.13.1"
|
||||
}
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
@@ -31649,21 +31694,17 @@
|
||||
}
|
||||
},
|
||||
"serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz",
|
||||
"integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==",
|
||||
"requires": {
|
||||
"type-fest": "^0.13.1"
|
||||
"type-fest": "^0.20.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -266,6 +266,7 @@
|
||||
"rxjs": "^7.8.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"semver": "^7.5.4",
|
||||
"serialize-error": "^8.1.0",
|
||||
"striptags": "^4.0.0-alpha.4",
|
||||
"tailwind-scrollbar-hide": "^1.1.7",
|
||||
"tailwindcss-scoped-groups": "^2.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio, spawn } from "child_process";
|
||||
import { Observable, ReplaySubject, Subscriber, filter, map, share } from "rxjs";
|
||||
import { DepotDownloaderArgsOptions, DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderEventTypes, DepotDownloaderInfoEvent, DepotDownloaderWarningEvent } from "../../shared/models/depot-downloader.model";
|
||||
import { DepotDownloaderArgsOptions, DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderEventTypes, DepotDownloaderInfoEvent, DepotDownloaderWarningEvent } from "../../shared/models/bs-version-download/depot-downloader.model";
|
||||
|
||||
export class DepotDownloader {
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ export class BsOculusDownloaderService {
|
||||
this.clearAuthToken();
|
||||
}
|
||||
|
||||
if(window.isClosable() && !window.isDestroyed()){
|
||||
if(!window.isDestroyed() && window.isClosable()){
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
@@ -146,12 +146,6 @@ export class BsOculusDownloaderService {
|
||||
public downloadVersion(downloadInfo: DownloadInfo): Observable<Progression<BSVersion>>{
|
||||
|
||||
return from(this.getUserTokenFromMetaAuth(downloadInfo.stay)).pipe(
|
||||
map(token => {
|
||||
if(!token){
|
||||
throw new CustomError("No token has been found while try to auto download Beat Saber from Oculus", "OCULUS_TOKEN_NEEDED");
|
||||
}
|
||||
return token;
|
||||
}),
|
||||
switchMap(token => {
|
||||
if(!downloadInfo.isVerification){
|
||||
return this.createDownloadVersion(downloadInfo.bsVersion).then(({version, dest}) => ({token, version, dest}))
|
||||
@@ -175,7 +169,7 @@ export class BsOculusDownloaderService {
|
||||
return from(this.getAuthToken()).pipe(
|
||||
map(token => {
|
||||
if(!token){
|
||||
throw new CustomError("No token has been found while try to auto download Beat Saber from Oculus", "OCULUS_TOKEN_NEEDED");
|
||||
throw new CustomError("No Meta auth token was found in cookies for auto download", "NO_META_AUTH_TOKEN");
|
||||
}
|
||||
return token;
|
||||
}),
|
||||
|
||||
@@ -9,7 +9,7 @@ import { BSLocalVersionService } from "../bs-local-version.service";
|
||||
import { ensureDir } from "fs-extra";
|
||||
import { ensurePathNotAlreadyExist } from "../../helpers/fs.helpers";
|
||||
import { Observable, catchError, finalize, map, throwError } from "rxjs";
|
||||
import { DepotDownloaderArgsOptions, DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderInfoEvent } from "../../../shared/models/depot-downloader.model";
|
||||
import { DepotDownloaderArgsOptions, DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderInfoEvent } from "../../../shared/models/bs-version-download/depot-downloader.model";
|
||||
import { DepotDownloader } from "../../models/depot-downloader.class";
|
||||
import { app } from "electron";
|
||||
import { BsStore } from "../../../shared/models/bs-store.enum";
|
||||
|
||||
@@ -3,6 +3,7 @@ import { BrowserWindow, ipcMain } from "electron";
|
||||
import { Observable } from "rxjs";
|
||||
import { IpcCompleteChannel, IpcErrorChannel, IpcTearDownChannel } from "shared/models/ipc/ipc-response.interface";
|
||||
import { IpcReplier } from "shared/models/ipc/ipc-request.interface";
|
||||
import { serializeError } from 'serialize-error';
|
||||
import log from "electron-log";
|
||||
|
||||
export class IpcService {
|
||||
@@ -47,7 +48,7 @@ export class IpcService {
|
||||
next: data => this.send(channel, window, data),
|
||||
error: error => {
|
||||
log.error(error);
|
||||
this.send(this.getErrorChannel(channel), window, error);
|
||||
this.send(this.getErrorChannel(channel), window, serializeError(error));
|
||||
},
|
||||
complete: () => this.send(this.getCompleteChannel(channel), window)
|
||||
})
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useService } from "renderer/hooks/use-service.hook";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
import { useObservable } from "renderer/hooks/use-observable.hook";
|
||||
import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service";
|
||||
import { BsStore } from "shared/models/bs-store.enum";
|
||||
|
||||
export const AvailableVersionsContext = createContext<{ selectedVersion: BSVersion; setSelectedVersion: (version: BSVersion) => void }>(null);
|
||||
|
||||
@@ -27,7 +28,10 @@ export function AvailableVersionsList() {
|
||||
|
||||
const startDownload = async () => {
|
||||
|
||||
const store = bsDownloader.getLastStoreDownloadedFrom() ?? await bsDownloader.chooseStoreToDownloadFrom().catch(() => null);
|
||||
const store = await (async () => {
|
||||
if(!selectedVersion.OculusBinaryId) { return BsStore.STEAM; }
|
||||
return bsDownloader.getLastStoreDownloadedFrom() ?? await bsDownloader.chooseStoreToDownloadFrom().catch(() => null);
|
||||
})();
|
||||
|
||||
if(!store){ return; }
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { LoginToMetaModal } from "renderer/components/modal/modal-types/bs-downg
|
||||
import { DownloaderServiceInterface } from "./bs-store-downloader.interface";
|
||||
import { AbstractBsDownloaderService } from "./abstract-bs-downloader.service";
|
||||
import { DownloadInfo } from "main/services/bs-version-download/bs-steam-downloader.service";
|
||||
import { MetaAuthErrorCodes } from "shared/models/bs-version-download/oculus-download.model";
|
||||
|
||||
export class OculusDownloaderService extends AbstractBsDownloaderService implements DownloaderServiceInterface{
|
||||
|
||||
@@ -44,33 +45,40 @@ export class OculusDownloaderService extends AbstractBsDownloaderService impleme
|
||||
this.notifications.notifyError({title: err.code});
|
||||
}
|
||||
|
||||
private handleDownload(download: Observable<Progression<BSVersion>>): Observable<Progression<BSVersion>> {
|
||||
private handleDownload(download: Observable<Progression<BSVersion>>, ingoreErrorCodes?: string[]): Observable<Progression<BSVersion>> {
|
||||
const progress$ = download.pipe(map(progress => (progress.current / progress.total) * 100), catchError(() => of(0)));
|
||||
this.progressBar.show(progress$, true);
|
||||
|
||||
const subs: Subscription[] = [];
|
||||
|
||||
subs.push(
|
||||
download.pipe(take(1), catchError(() => of(null))).subscribe(data => data && this._downloadingVersion$.next(data.data))
|
||||
download.pipe(take(1)).subscribe({ next: data => data && this._downloadingVersion$.next(data.data), error: () => {} })
|
||||
)
|
||||
|
||||
return download.pipe(
|
||||
tap({
|
||||
error: err => this.handleDownloadErrors(err),
|
||||
error: (err: CustomError) => {
|
||||
if(ingoreErrorCodes?.includes(err.code)){ return; }
|
||||
this.handleDownloadErrors(err);
|
||||
},
|
||||
}),
|
||||
finalize(() => subs.forEach(sub => sub.unsubscribe()))
|
||||
);
|
||||
}
|
||||
|
||||
private tryAutoDownload(downloadInfo: DownloadInfo): Observable<Progression<BSVersion>>{
|
||||
const ignoreCode = [MetaAuthErrorCodes.NO_META_AUTH_TOKEN];
|
||||
return this.handleDownload(
|
||||
this.ipc.sendV2<Progression<BSVersion>>("bs-oculus-auto-download", { args: downloadInfo })
|
||||
this.ipc.sendV2<Progression<BSVersion>>("bs-oculus-auto-download", { args: downloadInfo }),
|
||||
ignoreCode
|
||||
);
|
||||
}
|
||||
|
||||
private startDownloadBsVersion(downloadInfo: DownloadInfo): Observable<Progression<BSVersion>>{
|
||||
const ignoreCode = [MetaAuthErrorCodes.OCULUS_LOGIN_WINDOW_CLOSED_BY_USER];
|
||||
return this.handleDownload(
|
||||
this.ipc.sendV2<Progression<BSVersion>>("bs-oculus-download", { args: downloadInfo })
|
||||
this.ipc.sendV2<Progression<BSVersion>>("bs-oculus-download", { args: downloadInfo }),
|
||||
ignoreCode
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ProgressBarService } from "../progress-bar.service";
|
||||
import { LoginToSteamModal } from "renderer/components/modal/modal-types/bs-downgrade/login-to-steam-modal.component";
|
||||
import { SteamGuardModal } from "renderer/components/modal/modal-types/bs-downgrade/steam-guard-modal.component";
|
||||
import { LinkOpenerService } from "../link-opener.service";
|
||||
import { DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderInfoEvent, DepotDownloaderWarningEvent } from "../../../shared/models/depot-downloader.model";
|
||||
import { DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderInfoEvent, DepotDownloaderWarningEvent } from "../../../shared/models/bs-version-download/depot-downloader.model";
|
||||
import { SteamMobileApproveModal } from "renderer/components/modal/modal-types/bs-downgrade/steam-mobile-approve-modal.component";
|
||||
import { DownloaderServiceInterface } from "./bs-store-downloader.interface";
|
||||
import { AbstractBsDownloaderService } from "./abstract-bs-downloader.service";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defaultIfEmpty, share } from "rxjs/operators";
|
||||
import { Observable, ReplaySubject, identity } from "rxjs";
|
||||
import { IpcRequest, IpcResponse } from "shared/models/ipc";
|
||||
import { deserializeError } from 'serialize-error';
|
||||
import { IpcCompleteChannel, IpcErrorChannel, IpcTearDownChannel } from "shared/models/ipc/ipc-response.interface";
|
||||
|
||||
export class IpcService {
|
||||
@@ -77,7 +78,7 @@ export class IpcService {
|
||||
|
||||
const obs = new Observable<T>(observer => {
|
||||
window.electron.ipcRenderer.on(request.responceChannel, (res: T) => observer.next(res));
|
||||
window.electron.ipcRenderer.on(errorChannel, (err: Error) => observer.error(err));
|
||||
window.electron.ipcRenderer.on(errorChannel, (err) => observer.error(deserializeError(err)));
|
||||
window.electron.ipcRenderer.on(completeChannel, () => observer.complete());
|
||||
|
||||
window.electron.ipcRenderer.sendMessage(channel, request);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
export enum OculusDownloaderErrorCodes {
|
||||
DOWNLOAD_MANIFEST_ZIP_FAILED = "DOWNLOAD_MANIFEST_ZIP_FAILED",
|
||||
MANIFEST_FILE_NOT_FOUND = "MANIFEST_FILE_NOT_FOUND",
|
||||
PARSE_MANIFEST_FILE_FAILED = "PARSE_MANIFEST_FILE_FAILED",
|
||||
ALREADY_DOWNLOADING = "ALREADY_DOWNLOADING",
|
||||
UNABLE_TO_GET_MANIFEST = "UNABLE_TO_GET_MANIFEST",
|
||||
VERIFY_INTEGRITY_FAILED = "VERIFY_INTEGRITY_FAILED",
|
||||
SOME_FILES_FAILED_TO_DOWNLOAD = "SOME_FILES_FAILED_TO_DOWNLOAD",
|
||||
}
|
||||
|
||||
export enum MetaAuthErrorCodes {
|
||||
OCULUS_LOGIN_TIMED_OUT = "OCULUS_LOGIN_TIMED_OUT",
|
||||
OCULUS_LOGIN_WINDOW_CLOSED_BY_USER = "OCULUS_LOGIN_WINDOW_CLOSED_BY_USER",
|
||||
NO_META_AUTH_TOKEN = "NO_META_AUTH_TOKEN",
|
||||
}
|
||||
@@ -12,14 +12,25 @@ export class CustomError extends Error {
|
||||
public get code(): string { return this._code; }
|
||||
public get data(): unknown { return this._data; }
|
||||
|
||||
public static fromError(error: Error, code: string, data?: unknown): CustomError{
|
||||
public static fromError(error: Error, code?: string, data?: unknown): CustomError{
|
||||
|
||||
if(error instanceof CustomError){
|
||||
return error;
|
||||
}
|
||||
|
||||
code ||= (error as unknown as {code: string}).code || CustomErrorCodes.UNKNOWN_ERROR;
|
||||
|
||||
const customError = new CustomError(error.message ?? error.toString(), code, data);
|
||||
customError.stack = error.stack;
|
||||
return customError;
|
||||
}
|
||||
|
||||
public static throw(error: Error, code: string, data?: unknown): never{
|
||||
public static throw(error: Error, code?: string, data?: unknown): never{
|
||||
throw CustomError.fromError(error, code, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export enum CustomErrorCodes {
|
||||
UNKNOWN_ERROR = "UNKNOWN_ERROR",
|
||||
}
|
||||
Reference in New Issue
Block a user