From 9b7f90f5361dcafb6fe826971df95d24208c9ffa Mon Sep 17 00:00:00 2001 From: Richard Guerre Date: Mon, 19 Jul 2021 17:39:08 +0200 Subject: [PATCH 1/3] Fix v0.5.0 errors --- client/src/components/Settings/LogList.tsx | 8 +- electron/app/jobs/save-to-db/index.ts | 261 +++++++++++---------- electron/app/services/log-service.ts | 8 + 3 files changed, 156 insertions(+), 121 deletions(-) diff --git a/client/src/components/Settings/LogList.tsx b/client/src/components/Settings/LogList.tsx index 76b658e9..1feb13b8 100644 --- a/client/src/components/Settings/LogList.tsx +++ b/client/src/components/Settings/LogList.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Alert } from 'antd'; +import { Alert, Typography } from 'antd'; import { findAllLogs } from '../../services/logs-api'; import moment from 'moment'; @@ -46,6 +46,12 @@ export const LogList = () => { return ( <> + {logs.length > 0 ? ( + + You can ignore errors/warnings that are 10 minutes or older as they don't seem + to be repeating. + + ) : null} {logs.map(log => ( 0) { - // check if first summary item matches this.lastSavedSummary - if ( - this.lastSavedSummary?.endAt && - grouppedSummary[0].startAt <= - moment(this.lastSavedSummary.endAt).add(5, 'minutes').toDate() && - ((grouppedSummary[0].type === 'task' && - grouppedSummary[0].type === this.lastSavedSummary.type && - grouppedSummary[0].id === this.lastSavedSummary.id) || - (grouppedSummary[0].type === 'ticket' && - grouppedSummary[0].type === this.lastSavedSummary.type && - grouppedSummary[0].id === this.lastSavedSummary.id) || - (grouppedSummary[0].type === 'client_project' && + try { + // check if first summary item matches this.lastSavedSummary + if ( + this.lastSavedSummary?.endAt && + grouppedSummary[0].startAt <= + moment(this.lastSavedSummary.endAt).add(5, 'minutes').toDate() && + ((grouppedSummary[0].type === 'task' && grouppedSummary[0].type === this.lastSavedSummary.type && grouppedSummary[0].id === this.lastSavedSummary.id) || - (grouppedSummary[0].type === 'client' && - grouppedSummary[0].type === this.lastSavedSummary.type && - grouppedSummary[0].id.toString() === - this.lastSavedSummary.id.toString())) - ) { - // mutation to update worklog endAt field - const returned = await fetchGraphQLClient( - process.env.HASURA_GRAPHQL_ENGINE_DOMAIN, - { - token: this.token, - }, - )< - { - update_one_user_work_log: { - id: number; - } | null; - }, - { - worklogId: number; - worklogUpdates: { - endAt: string; - }; - } - >({ - operationAction: ` + (grouppedSummary[0].type === 'ticket' && + grouppedSummary[0].type === this.lastSavedSummary.type && + grouppedSummary[0].id === this.lastSavedSummary.id) || + (grouppedSummary[0].type === 'client_project' && + grouppedSummary[0].type === this.lastSavedSummary.type && + grouppedSummary[0].id === this.lastSavedSummary.id) || + (grouppedSummary[0].type === 'client' && + grouppedSummary[0].type === this.lastSavedSummary.type && + grouppedSummary[0].id.toString() === + this.lastSavedSummary.id.toString())) + ) { + // mutation to update worklog endAt field + const update = await fetchGraphQLClient( + process.env.HASURA_GRAPHQL_ENGINE_DOMAIN, + { + token: this.token, + }, + )< + { + update_one_user_work_log: { + id: number; + } | null; + }, + { + worklogId: number; + worklogUpdates: { + endAt: string; + }; + } + >({ + operationAction: ` mutation UpdateWorklog($worklogId: Int!, $worklogUpdates: user_work_logs_set_input!) { update_one_user_work_log: update_user_work_logs_by_pk(pk_columns: {id: $worklogId}, _set: $worklogUpdates) { id } } `, - variables: { - worklogId: this.lastSavedSummary.worklogId, - worklogUpdates: { - endAt: new Date(grouppedSummary[0].endAt).toJSON(), + variables: { + worklogId: this.lastSavedSummary.worklogId, + worklogUpdates: { + endAt: new Date(grouppedSummary[0].endAt).toJSON(), + }, }, - }, - }); + }); + + if ((update.errors?.length ?? 0) > 0) { + if ( + !update.errors.find((error) => + error.message.includes('UQ_USER_WORK_LOG_NON_OVERLAPPING'), + ) + ) { + throw new Error( + `Error updating user worklog | ${JSON.stringify( + update.errors, + )}`, + ); + } + } - if ((returned.errors?.length ?? 0) > 0) { - throw new Error( - `Error updating user worklog | ${JSON.stringify(returned.errors)}`, - ); - } + if (grouppedSummary.length === 1) { + this.lastSavedSummary = { + ...this.lastSavedSummary, + endAt: grouppedSummary[0].endAt, + }; + } - if (grouppedSummary.length === 1) { - this.lastSavedSummary = { - ...this.lastSavedSummary, - endAt: grouppedSummary[0].endAt, - }; + grouppedSummary.shift(); } - grouppedSummary.shift(); - } - - if (grouppedSummary.length > 0) { - // mutation to insert new user_worklogs - const update = await fetchGraphQLClient( - process.env.HASURA_GRAPHQL_ENGINE_DOMAIN, - { - token: this.token, - }, - )< - { - insert_user_work_logs: { - returning: { - id: number; - }[]; - }; - }, - { - worklogs: user_work_logs_insert_input[]; - } - >({ - operationAction: ` + if (grouppedSummary.length > 0) { + // mutation to insert new user_work_logs + const insert = await fetchGraphQLClient( + process.env.HASURA_GRAPHQL_ENGINE_DOMAIN, + { + token: this.token, + }, + )< + { + insert_user_work_logs: { + returning: { + id: number; + }[]; + }; + }, + { + worklogs: user_work_logs_insert_input[]; + } + >({ + operationAction: ` mutation InsertWorklogs($worklogs: [user_work_logs_insert_input!]!) { insert_user_work_logs(objects: $worklogs) { returning { @@ -317,53 +326,65 @@ export class SaveToDbJob { } } `, - variables: { - worklogs: grouppedSummary.map((summary) => ({ - startAt: new Date(summary.startAt).toJSON(), - endAt: new Date(summary.endAt).toJSON(), - workDescription: - 'This log was added automatically using data from the GitStart DevTime desktop app.', - ...(summary.type === 'task' ? { taskId: summary.id } : {}), - ...(summary.type === 'ticket' ? { ticketId: summary.id } : {}), - ...(summary.type === 'client_project' - ? { clientProjectId: summary.id } - : {}), - ...(summary.type === 'client' ? { clientId: summary.id } : {}), - technologyId: null, // TODO: get technology by extracting the file extension in the window title of VS Code events - workType: summary.type, - userId: user.id, - status: 'confirmed', - approvalStatus: 'auto', - billableToClient: false, - source: 'automatic from GitStart DevTime app', - })), - }, - }); - - if ((update.errors?.length ?? 0) > 0) { - // ignore the error if we've already added worklogs at those times - if ( - !update.errors.find((error) => - error.message.includes('UQ_USER_WORK_LOG_NON_OVERLAPPING'), - ) - ) { - throw new Error( - `Error inserting user worklog | ${JSON.stringify( - update.errors, - )}`, - ); + variables: { + worklogs: grouppedSummary.map((summary) => ({ + startAt: new Date(summary.startAt).toJSON(), + endAt: new Date(summary.endAt).toJSON(), + workDescription: + 'This log was added automatically using data from the GitStart DevTime desktop app.', + ...(summary.type === 'task' ? { taskId: summary.id } : {}), + ...(summary.type === 'ticket' + ? { ticketId: summary.id } + : {}), + ...(summary.type === 'client_project' + ? { clientProjectId: summary.id } + : {}), + ...(summary.type === 'client' + ? { clientId: summary.id } + : {}), + technologyId: null, // TODO: get technology by extracting the file extension in the window title of VS Code events + workType: summary.type, + userId: user.id, + status: 'confirmed', + approvalStatus: 'auto', + billableToClient: false, + source: 'automatic from GitStart DevTime app', + })), + }, + }); + + if ((insert.errors?.length ?? 0) > 0) { + // ignore the error if we've already added worklogs at those times + if ( + !insert.errors.find((error) => + error.message.includes('UQ_USER_WORK_LOG_NON_OVERLAPPING'), + ) + ) { + throw new Error( + `Error inserting user worklog | ${JSON.stringify( + insert.errors, + )}`, + ); + } } - } - const returningLength = update.data.insert_user_work_logs.returning.length; - this.lastSavedSummary = { - ...grouppedSummary[grouppedSummary.length - 1], - worklogId: - update.data.insert_user_work_logs.returning[returningLength - 1].id, - }; + const returningLength = + insert.data.insert_user_work_logs.returning.length; + this.lastSavedSummary = { + ...grouppedSummary[grouppedSummary.length - 1], + worklogId: + insert.data.insert_user_work_logs.returning[returningLength - 1] + .id, + }; + } + } catch (err) { + if (!err.message.includes('UQ_USER_WORK_LOG_NON_OVERLAPPING')) { + throw err; + } } } + console.log('Updating', events.length, 'events with isSummarized = true.'); const eventIds = events.map((event) => event.id); await TrackItem.query().whereIn('id', eventIds).patch({ updatedAt: new Date(), @@ -513,7 +534,7 @@ function logErrors(e: any) { .createOrUpdateLog({ type: 'ERROR', message: e.message, - jsonData: e.toString(), + jsonData: JSON.stringify(e), }) .catch(console.error); } diff --git a/electron/app/services/log-service.ts b/electron/app/services/log-service.ts index fa5510a4..1f0edea3 100644 --- a/electron/app/services/log-service.ts +++ b/electron/app/services/log-service.ts @@ -7,6 +7,14 @@ export class LogService { async createOrUpdateLog(logAttributes: Partial): Promise { let log: Log = null; + // Skip known/unfixable errors + if (logAttributes.message.includes("'endDate' of null")) { + return log; + } + if (logAttributes.message.includes('getaddrinfo ENOTFOUND hasura.gitstart.com')) { + logAttributes.message = + 'GitStart DevTime was disconnected. Please make sure you are connected to the internet.'; + } if ( this.lastLog && logAttributes.type === this.lastLog.type && From a71193fbf7d1304d0b327772a7288b65138b4659 Mon Sep 17 00:00:00 2001 From: Richard Guerre Date: Mon, 19 Jul 2021 17:45:21 +0200 Subject: [PATCH 2/3] minor touches --- client/src/components/Settings/LogList.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/components/Settings/LogList.tsx b/client/src/components/Settings/LogList.tsx index 1feb13b8..19e3b525 100644 --- a/client/src/components/Settings/LogList.tsx +++ b/client/src/components/Settings/LogList.tsx @@ -18,7 +18,7 @@ export const LogList = () => { const getAllLogs = async () => { const newLogs = await findAllLogs( moment() - .subtract(1, 'day') + .subtract(3, 'hours') .toDate(), ); setLogs(newLogs); @@ -49,7 +49,8 @@ export const LogList = () => { {logs.length > 0 ? ( You can ignore errors/warnings that are 10 minutes or older as they don't seem - to be repeating. + to be repeating. Repeating errors/warnings will update the time (i.e. "... ago") + to be less than 10 minutes. ) : null} {logs.map(log => ( From 3b18d20de913d67a3e2606e67f7eb3cb08413d33 Mon Sep 17 00:00:00 2001 From: Richard Guerre Date: Mon, 19 Jul 2021 22:14:41 +0200 Subject: [PATCH 3/3] add marginBottom --- client/src/components/Settings/LogList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Settings/LogList.tsx b/client/src/components/Settings/LogList.tsx index 19e3b525..b5dea0a1 100644 --- a/client/src/components/Settings/LogList.tsx +++ b/client/src/components/Settings/LogList.tsx @@ -47,7 +47,7 @@ export const LogList = () => { return ( <> {logs.length > 0 ? ( - + You can ignore errors/warnings that are 10 minutes or older as they don't seem to be repeating. Repeating errors/warnings will update the time (i.e. "... ago") to be less than 10 minutes.