From 1901f7c8a0b23f5a62f89784aa8071c074400bfa Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Tue, 24 Jan 2023 12:38:01 +0100 Subject: [PATCH] fix(ui): fix file loading, fix network request status display --- frontend/app/player/web/MessageManager.ts | 25 ++++++++-------- frontend/app/player/web/network/loadFiles.ts | 31 +++++++------------- frontend/app/types/session/resource.ts | 18 ++++-------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/frontend/app/player/web/MessageManager.ts b/frontend/app/player/web/MessageManager.ts index b4b7d0b7e..9ec41cc2a 100644 --- a/frontend/app/player/web/MessageManager.ts +++ b/frontend/app/player/web/MessageManager.ts @@ -30,7 +30,7 @@ import type { MouseClick, } from './messages'; -import { loadFiles, requestEFSDom, requestEFSDevtools } from './network/loadFiles'; +import { loadFiles, requestEFSDom, requestEFSDevtools, NO_FILE_OK } from './network/loadFiles'; import { decryptSessionBytes } from './network/crypto'; import Lists, { INITIAL_STATE as LISTS_INITIAL_STATE, State as ListsState } from './Lists'; @@ -220,20 +220,21 @@ export default class MessageManager { this.waitingForFiles = true - let fileReadPromise = this.session.domURL && this.session.domURL.length > 0 - ? loadFiles(this.session.domURL, createNewParser()) - : Promise.reject() - fileReadPromise + const loadMethod = this.session.domURL && this.session.domURL.length > 0 + ? { url: this.session.domURL, parser: createNewParser } + : { url: this.session.mobsUrl, parser: () => createNewParser(false)} + + loadFiles(loadMethod.url, loadMethod.parser()) // EFS fallback - .catch(() => requestEFSDom(this.session.sessionId).then(createNewParser(false))) - // old url fallback - .catch(e => { - logger.error('Can not get normal session replay file:', e) - // back compat fallback to an old mobsUrl - return loadFiles(this.session.mobsUrl, createNewParser(false)) + .catch((e) => { + if (e === NO_FILE_OK) { + console.log(e, 'getting unprocessed file') + requestEFSDom(this.session.sessionId).then(createNewParser(false)) + } else { + this.onFileReadFailed(e) + } }) .then(this.onFileReadSuccess) - .catch(this.onFileReadFailed) .finally(this.onFileReadFinally) // load devtools diff --git a/frontend/app/player/web/network/loadFiles.ts b/frontend/app/player/web/network/loadFiles.ts index d16433331..c878eea4b 100644 --- a/frontend/app/player/web/network/loadFiles.ts +++ b/frontend/app/player/web/network/loadFiles.ts @@ -1,31 +1,20 @@ import APIClient from 'App/api_client'; -const NO_FILE_OK = "No-file-but-this-is-ok" +export const NO_FILE_OK = "No-file-but-this-is-ok" const NO_BACKUP_FILE = "No-efs-file" -export const loadFiles = ( +export const loadFiles = async ( urls: string[], onData: (data: Uint8Array) => void, ): Promise => { if (!urls.length) { return Promise.reject("No urls provided") } - return urls.reduce((p, url, index) => - p.then(() => - window.fetch(url) - .then(r => { - return processAPIStreamResponse(r, index===0) - }) - .then(onData) - ), - Promise.resolve(), - ) - .catch(e => { - if (e === NO_FILE_OK) { - return - } - throw e - }) + for (let url of urls) { + const stream = await window.fetch(url) + const data = await processAPIStreamResponse(stream, url === urls[0]) + onData(data) + } } export async function requestEFSDom(sessionId: string) { @@ -47,8 +36,10 @@ async function requestEFSMobFile(filename: string) { const processAPIStreamResponse = (response: Response, canBeMissed: boolean) => { return new Promise((res, rej) => { - if (response.status === 404 && canBeMissed) { - return rej(NO_FILE_OK) + if (response.status === 404) { + if (canBeMissed) return rej(NO_FILE_OK) + // ignoring if 2nd mob file is missing + else return; } if (response.status >= 400) { return rej(`Bad file status code ${response.status}. Url: ${response.url}`) diff --git a/frontend/app/types/session/resource.ts b/frontend/app/types/session/resource.ts index c80603c50..7e09e8f02 100644 --- a/frontend/app/types/session/resource.ts +++ b/frontend/app/types/session/resource.ts @@ -10,7 +10,7 @@ const MEDIA = 'media' as const; const OTHER = 'other' as const; function getResourceStatus(status: number, success: boolean) { - if (status != null) return String(status); + if (status !== undefined) return String(status); if (typeof success === 'boolean' || typeof success === 'number') { return !!success ? '2xx-3xx' @@ -19,16 +19,6 @@ function getResourceStatus(status: number, success: boolean) { return '2xx-3xx'; } -function getResourceSuccess(success: boolean, status: number) { - if (success != null) { - return !!success - } - if (status != null) { - return status < 400 - } - return true -} - export const TYPES = { XHR, FETCH, @@ -94,16 +84,18 @@ export default class Resource { constructor({ status, success, time, datetime, timestamp, timings, ...resource }: IResource) { + // adjusting for 201, 202 etc + const reqSuccess = 300 > status || success Object.assign(this, { ...resource, name: getResourceName(resource.url), status: getResourceStatus(status, success), - success: getResourceSuccess(success, status), + success: reqSuccess, time: typeof time === 'number' ? time : datetime || timestamp, ttfb: timings && timings.ttfb, timewidth: timings && timings.timewidth, timings, - isRed: !success || resource.score >= RED_BOUND, + isRed: !reqSuccess || resource.score >= RED_BOUND, isYellow: resource.score < RED_BOUND && resource.score >= YELLOW_BOUND, }) }