diff --git a/src/components/advanced-table/advanced-table.tsx b/src/components/advanced-table/advanced-table.tsx index 348262f6..e8d3a3f4 100644 --- a/src/components/advanced-table/advanced-table.tsx +++ b/src/components/advanced-table/advanced-table.tsx @@ -13,6 +13,7 @@ import { Scheduler } from '../../handler'; import { AdvancedTableHeader } from './advanced-table-header'; import { useTranslator } from '../../hooks'; import { Alert } from '@mui/material'; +import { getErrorMessage } from '../../util/errors'; const PAGE_SIZE = 25; @@ -102,8 +103,9 @@ export function AdvancedTable< setNextToken(payload?.next_token); setTotalCount(payload?.total_count); }) - .catch((e: Error) => { - setDisplayError(e.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + setDisplayError(message); }); }; @@ -152,8 +154,9 @@ export function AdvancedTable< setPage(newPage); setMaxPage(newPage); }) - .catch((e: Error) => { - setDisplayError(e.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + setDisplayError(message); }); }; diff --git a/src/components/job-definition-row.tsx b/src/components/job-definition-row.tsx index 1bec1022..8562898a 100644 --- a/src/components/job-definition-row.tsx +++ b/src/components/job-definition-row.tsx @@ -16,6 +16,7 @@ import { Scheduler, SchedulerService } from '../handler'; import { useEventLogger, useTranslator } from '../hooks'; import { TranslationBundle } from '@jupyterlab/translation'; import { ConfirmDeleteButton } from './confirm-buttons'; +import { getErrorMessage } from '../util/errors'; function CreatedAt(props: { job: Scheduler.IDescribeJobDefinition; @@ -120,8 +121,9 @@ export function buildJobDefinitionRow( .then(_ => { forceReload(); }) - .catch((error: Error) => { - handleApiError(error.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + handleApiError(message); }); }} /> @@ -134,8 +136,9 @@ export function buildJobDefinitionRow( .then(_ => { forceReload(); }) - .catch((error: Error) => { - handleApiError(error.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + handleApiError(message); }); }} /> @@ -148,8 +151,9 @@ export function buildJobDefinitionRow( .then(_ => { deleteRow(jobDef.job_definition_id); }) - .catch((error: Error) => { - handleApiError(error.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + handleApiError(message); }); }} /> diff --git a/src/components/job-row.tsx b/src/components/job-row.tsx index 26f5a99f..97bbfff6 100644 --- a/src/components/job-row.tsx +++ b/src/components/job-row.tsx @@ -10,6 +10,7 @@ import { ICreateJobModel } from '../model'; import DownloadIcon from '@mui/icons-material/Download'; import StopIcon from '@mui/icons-material/Stop'; import { IconButton, Stack, Link, TableCell, TableRow } from '@mui/material'; +import { getErrorMessage } from '../util/errors'; function StopButton(props: { job: Scheduler.IDescribeJob; @@ -106,8 +107,9 @@ function DownloadFilesButton(props: DownloadFilesButtonProps) { props.reload(); }) ) - .catch((e: Error) => { - props.setDisplayError(e.message); + .catch((e: unknown) => { + const message = getErrorMessage(e); + props.setDisplayError(message); }); }} > @@ -178,7 +180,10 @@ export function buildJobRow( id: job.job_id }) .then(_ => deleteRow(job.job_id)) - .catch((e: Error) => setDisplayError(e.message)); + .catch((e: unknown) => { + const message = getErrorMessage(e); + setDisplayError(message); + }); }} /> setDisplayError(e.message)); + .catch((e: unknown) => { + const message = getErrorMessage(e); + setDisplayError(message); + }); }} /> diff --git a/src/context.ts b/src/context.ts index 0fd69767..c4aed731 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,10 +1,12 @@ import { ITranslator, nullTranslator } from '@jupyterlab/translation'; import React from 'react'; -export type Logger = (eventName: string) => void; -export const LogContext = React.createContext((eventName: string) => { - /*noop*/ -}); +export type Logger = (eventName: string, eventDetail?: string) => void; +export const LogContext = React.createContext( + (eventName: string, eventDetail?: string) => { + /*noop*/ + } +); // Context to be overridden with JupyterLab context const TranslatorContext = React.createContext(nullTranslator); diff --git a/src/index.tsx b/src/index.tsx index 3ab230a1..77875889 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -41,6 +41,11 @@ export namespace CommandIDs { export const NotebookJobsPanelId = 'notebook-jobs-panel'; export { Scheduler } from './tokens'; +type EventLog = { + body: { name: string; detail?: string }; + timestamp: Date; +}; + /** * Initialization data for the jupyterlab-scheduler extension. */ @@ -178,16 +183,21 @@ async function activatePlugin( let mainAreaWidget: MainAreaWidget | undefined; let jobsPanel: NotebookJobsPanel | undefined; - const eventLogger: Scheduler.EventLogger = eventName => { + const eventLogger: Scheduler.EventLogger = (eventName, eventDetail) => { if (!eventName) { return; } - const eventLog = { + const eventLog: EventLog = { body: { name: `org.jupyter.jupyter-scheduler.${eventName}` }, timestamp: new Date() }; + + if (eventDetail) { + eventLog.body.detail = eventDetail; + } + telemetryHandler(eventLog).then(); }; diff --git a/src/mainviews/create-job-from-definition.tsx b/src/mainviews/create-job-from-definition.tsx index 50834e07..97025f1e 100644 --- a/src/mainviews/create-job-from-definition.tsx +++ b/src/mainviews/create-job-from-definition.tsx @@ -13,6 +13,7 @@ import { Alert, Button, CircularProgress } from '@mui/material'; import { Box, Stack } from '@mui/system'; import { LabeledValue } from '../components/labeled-value'; +import { getErrorMessage } from '../util/errors'; export interface ICreateJobFromDefinitionProps { model: ICreateJobModel; @@ -139,6 +140,7 @@ export function CreateJobFromDefinition( createJobFromDefinitionModel ) .then(response => { + log('create-job-from-definition.create-job.success'); // Switch to the list view with "Job List" active props.showListView( JobsView.ListJobs, @@ -146,10 +148,12 @@ export function CreateJobFromDefinition( props.model.jobName ); }) - .catch((error: Error) => { + .catch((e: unknown) => { + const detail = getErrorMessage(e); + log('create-job-from-definition.create-job.failure', detail); props.handleModelChange({ ...props.model, - createError: error.message, + createError: detail, createInProgress: false }); }); @@ -240,7 +244,7 @@ export function CreateJobFromDefinition(