Skip to content

Commit

Permalink
Sentry errors (#606)
Browse files Browse the repository at this point in the history
* Enforce consistent api response destructuring (Sentry error dfc24eeb686f4f2288baec1c541ce36d)

* Avoid sending requests with undefined references (Sentry error 873d87beddb0406ba50ffa2a56a27f66)

* Avoid accessing properties of undefined objects (various Sentry errors)

* No optional chaining in template
  • Loading branch information
annehaley authored Sep 30, 2022
1 parent 3a23825 commit 41d0027
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 56 deletions.
3 changes: 2 additions & 1 deletion web_client/src/components/ControlPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ export default {
:decision="decision"
/>
<div
v-if="currentViewData.scanDecisions.length === 0"
v-if="!currentViewData.scanDecisions
|| currentViewData.scanDecisions.length === 0"
class="grey--text"
>
This scan has no prior comments.
Expand Down
1 change: 1 addition & 0 deletions web_client/src/components/WindowWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export default defineComponent({
</span>
</v-tooltip>
<custom-range-slider
v-if="currentRange && currentRange.length === 2"
:value="currentRange"
:disabled="windowLocked"
:max="widthMax"
Expand Down
130 changes: 75 additions & 55 deletions web_client/src/django.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable consistent-return */
import axios from 'axios';
import OAuthClient from '@girder/oauth-client';
import S3FileFieldClient from 'django-s3-file-field';
Expand Down Expand Up @@ -68,80 +69,93 @@ const djangoClient = {
},
async MIQAConfig() {
const response = await apiClient.get('/configuration/');
return response ? response.data : undefined;
return response?.data;
},
async globalSettings() {
const { data } = await apiClient.get('/global/settings');
return data;
const response = await apiClient.get('/global/settings');
return response?.data;
},
async globalImport(): Promise<ResponseData> {
return (await apiClient.post('/global/import')).data;
const response = await apiClient.post('/global/import');
return response?.data;
},
async projectImport(projectId: string): Promise<ResponseData> {
return (await apiClient.post(`/projects/${projectId}/import`)).data;
const response = await apiClient.post(`/projects/${projectId}/import`);
return response?.data;
},
async globalExport(): Promise<ResponseData> {
return (await apiClient.post('/global/export')).data;
const response = await apiClient.post('/global/export');
return response?.data;
},
async projectExport(projectId: string): Promise<ResponseData> {
return (await apiClient.post(`/projects/${projectId}/export`)).data;
if (!projectId) return undefined;
const response = await apiClient.post(`/projects/${projectId}/export`);
return response?.data;
},
async createProject(projectName: string): Promise<Project> {
const { data } = await apiClient.post('/projects', { name: projectName });
return data;
if (!projectName) return undefined;
const response = await apiClient.post('/projects', { name: projectName });
return response?.data;
},
async deleteProject(projectId: string): Promise<ResponseData> {
const { data } = await apiClient.delete(`/projects/${projectId}`);
return data;
if (!projectId) return undefined;
const response = await apiClient.delete(`/projects/${projectId}`);
return response?.data;
},
async projects(): Promise<Project[]> {
const { data } = await apiClient.get('/projects');
const { results } = data;
return results;
const response = await apiClient.get('/projects');
return response?.data?.results;
},
async project(projectId: string): Promise<Project> {
const { data } = await apiClient.get(`/projects/${projectId}`);
return data;
if (!projectId) return undefined;
const response = await apiClient.get(`/projects/${projectId}`);
return response?.data;
},
async projectTaskOverview(projectId: string): Promise<ProjectTaskOverview> {
const { data } = await apiClient.get(`/projects/${projectId}/task_overview`);
return data;
if (!projectId) return undefined;
const response = await apiClient.get(`/projects/${projectId}/task_overview`);
return response?.data;
},
async settings(projectId: string): Promise<ProjectSettings> {
const { data } = await apiClient.get(`/projects/${projectId}/settings`);
return data;
if (!projectId) return undefined;
const response = await apiClient.get(`/projects/${projectId}/settings`);
return response?.data;
},
async setGlobalSettings(settings: ProjectSettings): Promise<ResponseData> {
const resp = await apiClient.put('/global/settings', settings);
return resp.status === 200 ? resp.data : null;
if (!settings) return undefined;
const response = await apiClient.put('/global/settings', settings);
return response?.data;
},
async setProjectSettings(projectId: string, settings: ProjectSettings): Promise<ResponseData> {
const resp = await apiClient.put(`/projects/${projectId}/settings`, settings);
return resp.status === 200 ? resp.data : null;
if (!projectId || !settings) return undefined;
const response = await apiClient.put(`/projects/${projectId}/settings`, settings);
return response?.data;
},
async experiments(projectId: string): Promise<Experiment[]> {
const { data } = await apiClient.get('/experiments', {
if (!projectId) return undefined;
const response = await apiClient.get('/experiments', {
params: { project: projectId },
});
const { results } = data;
return results;
return response?.data?.results;
},
async experiment(experimentId: string): Promise<Experiment> {
const { data } = await apiClient.get(`/experiments/${experimentId}`);
return data;
if (!experimentId) return undefined;
const response = await apiClient.get(`/experiments/${experimentId}`);
return response?.data;
},
async createExperiment(projectId:string, experimentName: string): Promise<ResponseData> {
if (!projectId || !experimentName) return undefined;
const response = await apiClient.post('/experiments', {
project: projectId,
name: experimentName,
});
const { data } = response;
if (response.status === 500 && data.detail) {
throw new ErrorResponseDetail(data.detail);
if (response.status === 500 && response?.data?.detail) {
throw new ErrorResponseDetail(response.data.detail);
}
return data;
return response?.data;
},
async uploadToExperiment(experimentId: string, files: File[]) {
if (!experimentId || !files) return undefined;
// Promise.all maintains order so we can reference filenames by index
const uploadResponses = await Promise.all(files.map(
(file) => s3ffClient.uploadFile(file, 'core.Frame.content'),
Expand All @@ -155,27 +169,31 @@ const djangoClient = {
));
},
async setExperimentNote(experimentId: string, note: string): Promise<ResponseData> {
const { data } = await apiClient.post(`/experiments/${experimentId}/note`, { note });
return data;
if (!experimentId) return undefined;
const response = await apiClient.post(`/experiments/${experimentId}/note`, { note });
return response?.data;
},
async lockExperiment(experimentId: string, force: boolean): Promise<ResponseData> {
const { data } = await apiClient.post(`/experiments/${experimentId}/lock`, { force });
return data;
if (!experimentId) return undefined;
const response = await apiClient.post(`/experiments/${experimentId}/lock`, { force });
return response?.data;
},
async unlockExperiment(experimentId: string): Promise<ResponseData> {
const { data } = await apiClient.delete(`/experiments/${experimentId}/lock`);
return data;
if (!experimentId) return undefined;
const response = await apiClient.delete(`/experiments/${experimentId}/lock`);
return response?.data;
},
async scans(experimentId: string): Promise<Scan[]> {
const { data } = await apiClient.get('/scans', {
if (!experimentId) return undefined;
const response = await apiClient.get('/scans', {
params: { experiment: experimentId },
});
const { results } = data;
return results;
return response?.data?.results;
},
async scan(scanId: string): Promise<Scan> {
const { data } = await apiClient.get(`/scans/${scanId}`);
return data;
if (!scanId) return undefined;
const response = await apiClient.get(`/scans/${scanId}`);
return response?.data;
},
async setDecision(
scanId: string,
Expand All @@ -184,29 +202,31 @@ const djangoClient = {
userIdentifiedArtifacts: Object,
location: Object,
): Promise<ResponseData> {
const { data } = await apiClient.post('/scan-decisions', {
if (!scanId) return undefined;
const response = await apiClient.post('/scan-decisions', {
scan: scanId, decision, note: comment, artifacts: userIdentifiedArtifacts, location,
});
return data;
return response?.data;
},
async frames(scanId: string): Promise<Frame[]> {
const { data } = await apiClient.get('/frames', {
if (!scanId) return undefined;
const response = await apiClient.get('/frames', {
params: { scan: scanId },
});
const { results } = data;
return results;
return response?.data?.results;
},
async frame(frameId: string): Promise<Frame> {
const { data } = await apiClient.get(`/frames/${frameId}`);
return data;
if (!frameId) return undefined;
const response = await apiClient.get(`/frames/${frameId}`);
return response?.data;
},
async me(): Promise<User> {
const resp = await apiClient.get('/users/me');
return resp && resp.status === 200 ? resp.data : null;
const response = await apiClient.get('/users/me');
return response?.data;
},
async allUsers(): Promise<Paginated<User>> {
const resp = await apiClient.get('/users');
return resp.status === 200 ? resp.data : null;
const response = await apiClient.get('/users');
return response?.data;
},
async sendEmail(email: Email) {
await apiClient.post('/email', email);
Expand Down
1 change: 1 addition & 0 deletions web_client/src/utils/crosshairs.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CrosshairSet {
}

getSliceLines() {
if (!this.imageData) return undefined;
const [iMax, jMax, kMax] = this.imageData.getDimensions();

const iRepresentation = [
Expand Down

0 comments on commit 41d0027

Please sign in to comment.