diff --git a/src/background/actions.ts b/src/background/actions.ts index dfd6a6b..5ae145b 100644 --- a/src/background/actions.ts +++ b/src/background/actions.ts @@ -19,14 +19,14 @@ export function redirectTab(tab: chrome.tabs.Tab, url: string) { let queryErr: any; let newURL = await queryUrl(tab).catch(e => queryErr = e); if (queryErr) { - return Promise.reject(queryErr); + throw queryErr; } if (newURL == url) return url; if ( tryCount % 1 == 0 && !confirm('Cannot navigate to target url. \nPress OK to continue, Cancel to stop.') ) { - return Promise.reject("Tasks stopped by user."); + throw "Tasks stopped by user."; } return undefined; } diff --git a/src/background/messaging.ts b/src/background/messaging.ts index 3429250..d5c3357 100644 --- a/src/background/messaging.ts +++ b/src/background/messaging.ts @@ -50,40 +50,18 @@ export function sendMessage( chrome.tabs.sendMessage(tab.id, req, async (r: Response) => { // check error but do nothing until dataChecker. let err = chrome.runtime.lastError; - let result: T; - // r could be undefined if the content script is interrupted. - if (r) { - result = r.result; - - if (dataChecker) { - let pms: T | Promise; - try { - pms = dataChecker(r, err, count); - } catch (error) { - reject(error); - return; - } - // don't catch if it's not a Promise - if (pms instanceof Promise) { - let checkerError: any; - pms = pms.catch(e => checkerError = e); - result = await pms; - if (checkerError) { - reject(checkerError); - return; - } - } else { - result = pms; - } - } + let [result, error] = await checkResponse(dataChecker, r, err, count); + if (error) { + reject(error); + return; } - - let flag = result !== undefined && result !== null; + let flag = result !== undefined; if (log) logger.info(log, flag ? '(OK)' : '(failed)'); if (flag) { resolve(result); } else { setTimeout(() => { + logger.debug('Invalid response', r, 'retry...'); loop(); }, interval); } @@ -92,6 +70,39 @@ export function sendMessage( }); } +async function checkResponse( + dataChecker: ResponseChecker, + response: Response, + error: chrome.runtime.LastError, + tryCount: number +): Promise<[T, string]> { + // response could be undefined if the content script is interrupted. + // don't check, tell sendMessage to retry. + if (!response) return [undefined, undefined]; + if (!dataChecker) { + return [response.result, response.error]; + } + let result: T; + let pms: T | Promise; + try { + pms = dataChecker(response, error, tryCount); + } catch (err) { + return [undefined, err]; + } + // don't catch if it's not a Promise + if (pms instanceof Promise) { + let checkerError: any; + pms = pms.catch(e => checkerError = e); + result = await pms; + if (checkerError) { + return [undefined, checkerError]; + } + } else { + result = pms; + } + return [result, undefined]; +} + export type ActionSubscriberSync = (request: Request, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => void; export type ActionSubscriberAsync = (request: Request, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => Promise; export type ActionSubscriber = ActionSubscriberSync | ActionSubscriberAsync; diff --git a/src/background/task.ts b/src/background/task.ts index d630e19..93230c5 100644 --- a/src/background/task.ts +++ b/src/background/task.ts @@ -103,8 +103,8 @@ export class Task { messageSubscribers.addListener(Actions.REPORT_NEW_PAGE, listener); } async execute(tab: chrome.tabs.Tab, upstreamData?: ExtractResult): Promise { - if (!tab) return Promise.reject("No tab to execute the task."); - if (this._running) return Promise.reject("The task is running. Please wait..."); + if (!tab) throw "No tab to execute the task."; + if (this._running) throw "The task is running. Please wait..."; this._running = true; let urls = this._urls if (!urls.length) { @@ -140,7 +140,7 @@ export class Task { ).catch( e => { this._running = false; - return Promise.reject(e); + throw e; } ); } @@ -152,7 +152,7 @@ export class Task { return pm; } private runningCheck(fn: () => Promise): Promise { - if (!this._running) return Promise.reject("The task is stopped by user."); + if (!this._running) throw "The task is stopped by user."; return fn(); } private saveResult(results, key) {