chore(ui): handle trace not being available without exceptions

This commit is contained in:
Simon Knott 2024-11-04 15:58:41 +01:00
parent b148ce1ad1
commit d8725a3c16
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 18 additions and 8 deletions

View file

@ -54,6 +54,8 @@ async function loadTrace(traceUrl: string, traceFileName: string | null, clientI
const backend = traceUrl.endsWith('json') ? new FetchTraceModelBackend(traceUrl) : new ZipTraceModelBackend(traceUrl, fetchProgress);
await traceModel.load(backend, unzipProgress);
} catch (error: any) {
if (error?.message === 'trace not found')
throw error;
// eslint-disable-next-line no-console
console.error(error);
if (error?.message?.includes('Cannot find .trace file') && await traceModel.hasEntry('index.html'))
@ -106,6 +108,8 @@ async function doFetch(event: FetchEvent): Promise<Response> {
headers: { 'Content-Type': 'application/json' }
});
} catch (error: any) {
if (error?.message === 'trace not found')
return new Response(null, { status: 404 });
return new Response(JSON.stringify({ error: error?.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' }

View file

@ -88,7 +88,10 @@ export class FetchTraceModelBackend implements TraceModelBackend {
constructor(traceURL: string) {
this._traceURL = traceURL;
this._entriesPromise = fetch('/trace/file?path=' + encodeURIComponent(traceURL)).then(async response => {
const json = JSON.parse(await response.text());
if (response.status === 404)
throw new Error(`trace not found`);
const json = await response.json();
const entries = new Map<string, string>();
for (const entry of json.entries)
entries.set(entry.name, entry.path);

View file

@ -33,7 +33,6 @@ export const TraceView: React.FC<{
pathSeparator: string,
}> = ({ item, rootDir, onOpenExternally, revealSource, pathSeparator }) => {
const [model, setModel] = React.useState<{ model: MultiTraceModel, isLive: boolean } | undefined>();
const [counter, setCounter] = React.useState(0);
const pollTimer = React.useRef<NodeJS.Timeout | null>(null);
const { outputDir } = React.useMemo(() => {
@ -54,7 +53,10 @@ export const TraceView: React.FC<{
// Test finished.
const attachment = result && result.duration >= 0 && result.attachments.find(a => a.name === 'trace');
if (attachment && attachment.path) {
loadSingleTraceFile(attachment.path).then(model => setModel({ model, isLive: false }));
loadSingleTraceFile(attachment.path).then(model => {
if (model)
setModel({ model, isLive: false });
});
return;
}
@ -73,18 +75,17 @@ export const TraceView: React.FC<{
pollTimer.current = setTimeout(async () => {
try {
const model = await loadSingleTraceFile(traceLocation);
setModel({ model, isLive: true });
if (model)
setModel({ model, isLive: true });
} catch {
setModel(undefined);
} finally {
setCounter(counter + 1);
}
}, 500);
return () => {
if (pollTimer.current)
clearTimeout(pollTimer.current);
};
}, [outputDir, item, setModel, counter, setCounter, pathSeparator]);
}, [outputDir, item, setModel, pathSeparator]);
return <Workbench
key='workbench'
@ -108,11 +109,13 @@ const outputDirForTestCase = (testCase: reporterTypes.TestCase): string | undefi
return undefined;
};
async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
async function loadSingleTraceFile(url: string): Promise<MultiTraceModel | undefined> {
const params = new URLSearchParams();
params.set('trace', url);
params.set('limit', '1');
const response = await fetch(`contexts?${params.toString()}`);
if (response.status === 404)
return;
const contextEntries = await response.json() as ContextEntry[];
return new MultiTraceModel(contextEntries);
}