Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended error logging #6844

Merged
merged 12 commits into from
Sep 13, 2023
8 changes: 7 additions & 1 deletion cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,13 @@ export class CanvasViewImpl implements CanvasView, Listener {
}
if (e.altKey) {
const { points } = state;
this.onEditDone(state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)));
if (
(state.shapeType === 'polygon' && state.points.length > 6) ||
(state.shapeType === 'polyline' && state.points.length > 4) ||
(state.shapeType === 'points' && state.points.length > 2)
) {
this.onEditDone(state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)));
}
} else if (e.shiftKey) {
this.onEditStart(state);
this.editHandler.edit({
Expand Down
3 changes: 1 addition & 2 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import AnnotationGuide from './guide';
import * as enums from './enums';

import {
Exception, ArgumentError, DataError, ScriptingError, PluginError, ServerError,
Exception, ArgumentError, DataError, ScriptingError, ServerError,
} from './exceptions';

import User from './user';
Expand Down Expand Up @@ -249,7 +249,6 @@ function build() {
ArgumentError,
DataError,
ScriptingError,
PluginError,
ServerError,
},
cloudStorages: {
Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/download.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ onmessage = (e) => {
.catch((error) => {
postMessage({
id: e.data.id,
status: error.response.status,
responseData: error.response.data,
message: error.message,
code: error.code,
isSuccess: false,
});
});
Expand Down
2 changes: 0 additions & 2 deletions cvat-core/src/exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ export class DataError extends Exception {}

export class ScriptingError extends Exception {}

export class PluginError extends Exception {}

export class ServerError extends Exception {
constructor(message, code) {
super(message);
Expand Down
36 changes: 10 additions & 26 deletions cvat-core/src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT

import { PluginError } from './exceptions';
import { ArgumentError } from './exceptions';

const plugins = [];

Expand All @@ -21,18 +21,10 @@ export default class PluginRegistry {
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.enter) {
try {
const options: APIWrapperEnterOptions | undefined = await pluginDecorators
.enter.call(this, plugin, ...args);
if (options?.preventMethodCall) {
aggregatedOptions.preventMethodCall = true;
}
} catch (exception) {
if (exception instanceof PluginError) {
throw exception;
} else {
throw new PluginError(`Exception in plugin ${plugin.name}: ${exception.toString()}`);
}
const options: APIWrapperEnterOptions | undefined = await pluginDecorators
.enter.call(this, plugin, ...args);
if (options?.preventMethodCall) {
aggregatedOptions.preventMethodCall = true;
}
}
}
Expand All @@ -45,15 +37,7 @@ export default class PluginRegistry {
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.leave) {
try {
result = await pluginDecorators.leave.call(this, plugin, result, ...args);
} catch (exception) {
if (exception instanceof PluginError) {
throw exception;
} else {
throw new PluginError(`Exception in plugin ${plugin.name}: ${exception.toString()}`);
}
}
result = await pluginDecorators.leave.call(this, plugin, result, ...args);
}
}

Expand All @@ -65,19 +49,19 @@ export default class PluginRegistry {
const functions = [];

if (typeof plug !== 'object') {
throw new PluginError(`Plugin should be an object, but got "${typeof plug}"`);
throw new ArgumentError(`Plugin should be an object, but got "${typeof plug}"`);
}

if (!('name' in plug) || typeof plug.name !== 'string') {
throw new PluginError('Plugin must contain a "name" field and it must be a string');
throw new ArgumentError('Plugin must contain a "name" field and it must be a string');
}

if (!('description' in plug) || typeof plug.description !== 'string') {
throw new PluginError('Plugin must contain a "description" field and it must be a string');
throw new ArgumentError('Plugin must contain a "description" field and it must be a string');
}

if ('functions' in plug) {
throw new PluginError('Plugin must not contain a "functions" field');
throw new ArgumentError('Plugin must not contain a "functions" field');
}

function traverse(plugin, api) {
Expand Down
41 changes: 13 additions & 28 deletions cvat-core/src/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,26 +197,20 @@ class WorkerWrappedAxios {

worker.onmessage = (e) => {
if (e.data.id in requests) {
if (e.data.isSuccess) {
requests[e.data.id].resolve(e.data.responseData);
} else {
requests[e.data.id].reject({
response: {
status: e.data.status,
data: e.data.responseData,
},
});
try {
if (e.data.isSuccess) {
requests[e.data.id].resolve(e.data.responseData);
} else {
requests[e.data.id].reject(new AxiosError(e.data.message, e.data.code));
}
} finally {
delete requests[e.data.id];
}

delete requests[e.data.id];
}
};

worker.onerror = (e) => {
if (e.data.id in requests) {
requests[e.data.id].reject(e);
delete requests[e.data.id];
}
worker.onerror = () => {
throw new Error('Unexpected download worker error');
};

function getRequestId(): number {
Expand All @@ -226,10 +220,7 @@ class WorkerWrappedAxios {
async function get(url: string, requestConfig) {
return new Promise((resolve, reject) => {
const newRequestId = getRequestId();
requests[newRequestId] = {
resolve,
reject,
};
requests[newRequestId] = { resolve, reject };
worker.postMessage({
url,
config: requestConfig,
Expand Down Expand Up @@ -1508,7 +1499,7 @@ async function getData(jid: number, chunk: number, quality: ChunkQuality): Promi
const { backendAPI } = config;

try {
const response = await workerAxios.get(`${backendAPI}/jobs/${jid}/data`, {
const response = await (workerAxios as any).get(`${backendAPI}/jobs/${jid}/data`, {
params: {
...enableOrganization(),
quality,
Expand All @@ -1520,13 +1511,7 @@ async function getData(jid: number, chunk: number, quality: ChunkQuality): Promi

return response;
} catch (errorData) {
throw generateError({
message: '',
response: {
...errorData.response,
data: String.fromCharCode.apply(null, new Uint8Array(errorData.response.data)),
},
});
throw generateError(errorData);
}
}

Expand Down
26 changes: 14 additions & 12 deletions cvat-data/src/ts/cvat-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,20 @@ export function decodeContextImages(
const result: Record<string, ImageBitmap> = {};
let decoded = 0;

decodeZipWorker.onerror = (e: ErrorEvent) => {
decodeZipWorker.onerror = (event: ErrorEvent) => {
release();
reject(new Error(`Archive can not be decoded. ${e.message}`));
reject(event.error);
};

decodeZipWorker.onmessage = async (event) => {
const { error, fileName } = event.data;
if (error) {
decodeZipWorker.onerror(new ErrorEvent('error', { message: error.toString() }));
if (event.data.error) {
this.zipWorker.onerror(new ErrorEvent('error', {
error: event.data.error,
}));
return;
}

const { data } = event.data;
const { data, fileName } = event.data;
result[fileName.split('.')[0]] = data;
decoded++;

Expand Down Expand Up @@ -253,10 +254,10 @@ export class FrameDecoder {
index++;
};

worker.onerror = () => {
worker.onerror = (event: ErrorEvent) => {
release();
worker.terminate();
this.chunkIsBeingDecoded.onReject(new Error('Error occured during decode'));
this.chunkIsBeingDecoded.onReject(event.error);
this.chunkIsBeingDecoded = null;
};

Expand Down Expand Up @@ -290,7 +291,9 @@ export class FrameDecoder {

this.zipWorker.onmessage = async (event) => {
if (event.data.error) {
this.zipWorker.onerror(new ErrorEvent('error', { message: event.data.error.toString() }));
this.zipWorker.onerror(new ErrorEvent('error', {
error: event.data.error,
}));
return;
}

Expand All @@ -306,10 +309,9 @@ export class FrameDecoder {
index++;
};

this.zipWorker.onerror = () => {
this.zipWorker.onerror = (event: ErrorEvent) => {
release();

this.chunkIsBeingDecoded.onReject(new Error('Error occured during decode'));
this.chunkIsBeingDecoded.onReject(event.error);
this.chunkIsBeingDecoded = null;
};

Expand Down
83 changes: 51 additions & 32 deletions cvat-data/src/ts/unzip_imgs.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,57 @@
const JSZip = require('jszip');

onmessage = (e) => {
const zip = new JSZip();
if (e.data) {
const {
start, end, block, dimension, dimension2D,
} = e.data;
let errored = false;
function handleError(error) {
try {
if (!errored) {
postMessage({ error });
}
} finally {
errored = true;
}
}

try {
const zip = new JSZip();
if (e.data) {
const {
start, end, block, dimension, dimension2D,
} = e.data;

zip.loadAsync(block).then((_zip) => {
let index = start;

zip.loadAsync(block).then((_zip) => {
let index = start;
_zip.forEach((relativePath) => {
const fileIndex = index++;
if (fileIndex <= end) {
_zip.file(relativePath)
.async('blob')
.then((fileData) => {
if (dimension === dimension2D) {
createImageBitmap(fileData).then((img) => {
postMessage({
fileName: relativePath,
index: fileIndex,
data: img,
});
});
} else {
postMessage({
fileName: relativePath,
index: fileIndex,
data: fileData,
});
}
});
}
});
}).catch((error) => postMessage({ error }));
_zip.forEach((relativePath) => {
const fileIndex = index++;
if (fileIndex <= end) {
_zip.file(relativePath)
.async('blob')
.then((fileData) => {
if (!errored) {
// do not need to read the rest of block if an error already occured
if (dimension === dimension2D) {
createImageBitmap(fileData).then((img) => {
postMessage({
fileName: relativePath,
index: fileIndex,
data: img,
});
});
} else {
postMessage({
fileName: relativePath,
index: fileIndex,
data: fileData,
});
}
}
}).catch(handleError);
}
});
}).catch(handleError);
}
} catch (error) {
handleError(error);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Button from 'antd/lib/button';
import { DeleteOutlined, EnvironmentOutlined } from '@ant-design/icons';
import { connect } from 'react-redux';

import { CombinedState, ContextMenuType } from 'reducers';
import { CombinedState, ContextMenuType, ShapeType } from 'reducers';
import { updateAnnotationsAsync, updateCanvasContextMenu } from 'actions/annotation-actions';
import CVATTooltip from 'components/common/cvat-tooltip';

Expand Down Expand Up @@ -103,16 +103,23 @@ function CanvasPointContextMenu(props: Props): React.ReactPortal | null {
return visible && contextMenuFor && type === ContextMenuType.CANVAS_SHAPE_POINT ?
ReactDOM.createPortal(
<div className='cvat-canvas-point-context-menu' style={{ top, left }}>
<CVATTooltip title='Delete point [Alt + dblclick]'>
<Button
type='link'
icon={<DeleteOutlined />}
onClick={onPointDelete}
className='cvat-canvas-point-context-menu-delete'
>
Delete point
</Button>
</CVATTooltip>
{contextMenuFor && (
(contextMenuFor.shapeType === ShapeType.POLYGON && contextMenuFor.points.length > 6) ||
(contextMenuFor.shapeType === ShapeType.POLYLINE && contextMenuFor.points.length > 4) ||
(contextMenuFor.shapeType === ShapeType.POINTS && contextMenuFor.points.length > 2)) &&
(
<CVATTooltip title='Delete point [Alt + dblclick]'>
<Button
type='link'
icon={<DeleteOutlined />}
onClick={onPointDelete}
className='cvat-canvas-point-context-menu-delete'
>
Delete point
</Button>
</CVATTooltip>
)}

{contextMenuFor && contextMenuFor.shapeType === 'polygon' && (
<Button
type='link'
Expand Down
Loading