Skip to content

Commit 49f6406

Browse files
author
koubaalo
committed
[#20273] Improve error format and output for FE
1 parent d915e85 commit 49f6406

File tree

6 files changed

+77
-75
lines changed

6 files changed

+77
-75
lines changed

src/jobs/remove_obsolete_mappings_job.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class RemoveObsoleteMappingsJob extends SyncJob {
100100
if (!syncedService) continue;
101101
let operationOk = true;
102102
try {
103-
operationOk = await syncedService.deleteServiceObject(mappingObject.id, mappingObject.type);
103+
operationOk = await syncedService.deleteServiceObject(mappingObject.id, mappingObject.type, mappingObject.name);
104104
} catch (ex: any) {
105105
if (ex.status === 404) {
106106
// service object is missing, it is ok to delete the mapping
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export class T2tErrorExtraContext {
2+
service!: string;
3+
functionName!: string;
4+
objectId: string | null = null;
5+
objectExtraInformation: string[] = [];
6+
responseErrors: string[] = [];
7+
8+
constructor(service: string, functionName: string, objectId: string | null = null, objectExtraInformation: string[] = []) {
9+
this.service = service;
10+
this.functionName = functionName;
11+
this.objectId = objectId;
12+
this.objectExtraInformation = objectExtraInformation;
13+
}
14+
}

src/models/timer2TicketError.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
import {T2tErrorExtraContext} from "./t2t_error_extra_context";
12

23

34
export class Timer2TicketError {
45
specification: string;
56
exception: unknown;
6-
data: unknown;
7+
data: T2tErrorExtraContext | undefined;
78

89

910
constructor() {
1011
this.specification = "";
1112
this.exception = {};
12-
this.data = {};
13+
this.data = undefined;
1314
}
1415
}

src/synced_services/redmine/redmine_synced_service.ts

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {ServiceTimeEntryObject} from "../../models/synced_service/time_entry_syn
1717
import {IssueStatus} from "../../models/synced_service/redmine/issue_status";
1818
import {ProjectStatus} from "../../models/synced_service/redmine/project_status";
1919
import {ExtraContext} from "../../models/extra_context";
20+
import {T2tErrorExtraContext} from "../../models/t2t_error_extra_context";
2021

2122
export class RedmineSyncedService implements SyncedService {
2223
private _serviceDefinition: ServiceDefinition;
@@ -83,11 +84,10 @@ export class RedmineSyncedService implements SyncedService {
8384
* Plus waiting if responded with 429 Too many requests.
8485
* (Seems like Redmine does not respond with 429, but handled just in case.)
8586
* @param request
86-
* @param functionInfo
8787
* @param extraContext
8888
* @returns
8989
*/
90-
private async _retryAndWaitInCaseOfTooManyRequests(request: SuperAgentRequest, functionInfo: string, extraContext?: any): Promise<superagent.Response> {
90+
private async _retryAndWaitInCaseOfTooManyRequests(request: SuperAgentRequest, extraContext: T2tErrorExtraContext): Promise<superagent.Response> {
9191
let needToWait = false;
9292

9393
// call request but with chained retry
@@ -100,7 +100,7 @@ export class RedmineSyncedService implements SyncedService {
100100
}
101101
})
102102
.catch(err => {
103-
this.handleResponseException(err, functionInfo, extraContext)
103+
this.handleResponseException(err, extraContext)
104104
return err;
105105
});
106106

@@ -271,7 +271,7 @@ export class RedmineSyncedService implements SyncedService {
271271
.accept('application/json')
272272
.type('application/json')
273273
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
274-
'getAllProjects'
274+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getAllProjects')
275275
);
276276

277277
response.body?.projects.forEach((project: never) => {
@@ -302,7 +302,7 @@ export class RedmineSyncedService implements SyncedService {
302302
.accept('application/json')
303303
.type('application/json')
304304
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
305-
'fetchIssues'
305+
new T2tErrorExtraContext(this._serviceDefinition.name, 'fetchIssues')
306306
);
307307

308308
responseIssues.body?.issues.forEach((issue: never) => {
@@ -346,7 +346,7 @@ export class RedmineSyncedService implements SyncedService {
346346
.accept('application/json')
347347
.type('application/json')
348348
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
349-
'getAllAdditionalSOs for issues'
349+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getAllAdditionalSOs for issues')
350350
);
351351

352352
responseIssues.body?.issues.forEach((issue: never) => {
@@ -370,7 +370,7 @@ export class RedmineSyncedService implements SyncedService {
370370
.accept('application/json')
371371
.type('application/json')
372372
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
373-
'getAllAdditionalSOs for timeEntryActivities'
373+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getAllAdditionalSOs for timeEntryActivities')
374374
);
375375

376376
responseTimeEntryActivities.body?.time_entry_activities.forEach((timeEntryActivity: never) => {
@@ -411,7 +411,7 @@ export class RedmineSyncedService implements SyncedService {
411411
.accept('application/json')
412412
.type('application/json')
413413
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
414-
'getTimeEntries'
414+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getTimeEntries')
415415
);
416416

417417
response.body['time_entries'].forEach((timeEntry: never) => {
@@ -451,8 +451,7 @@ export class RedmineSyncedService implements SyncedService {
451451
.accept('application/json')
452452
.type('application/json')
453453
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
454-
'getTimeEntryById',
455-
{ timeEntryId: id }
454+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getTimeEntryById', id.toString())
456455
);
457456
} catch (err: any) {
458457
if (err && (err.status === 403 || err.status === 404)) {
@@ -522,7 +521,7 @@ export class RedmineSyncedService implements SyncedService {
522521
.accept('application/json')
523522
.type('application/json')
524523
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
525-
'getTimeEntriesRelatedToMappingObjectForUser'
524+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getTimeEntriesRelatedToMappingObjectForUser', mapping.primaryObjectId.toString())
526525
);
527526
} catch (err: any) {
528527
//console.log('[OMR] -> chyteny error v response try - catch bloku!');
@@ -628,8 +627,7 @@ export class RedmineSyncedService implements SyncedService {
628627
.type('application/json')
629628
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey)
630629
.send({ time_entry: timeEntryBody }),
631-
'createTimeEntry',
632-
timeEntryBody
630+
new T2tErrorExtraContext(this._serviceDefinition.name, 'createTimeEntry', null, ["TE started: " + start.toISOString()])
633631
);
634632

635633
if (!response || !response.ok) {
@@ -772,8 +770,7 @@ export class RedmineSyncedService implements SyncedService {
772770
.type('application/json')
773771
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey)
774772
.send({ time_entry: timeEntryBody }),
775-
'updateTimeEntry',
776-
timeEntryBody
773+
new T2tErrorExtraContext(this._serviceDefinition.name, 'updateTimeEntry', originalTimeEntry.originalEntry.id.toString(), ["TE started: " + start.toISOString()])
777774
);
778775

779776
const updated = await this.getTimeEntryById(originalTimeEntry.originalEntry.id);
@@ -798,8 +795,7 @@ export class RedmineSyncedService implements SyncedService {
798795
.accept('application/json')
799796
.type('application/json')
800797
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
801-
'deleteTimeEntry',
802-
{ timeEntryId: id }
798+
new T2tErrorExtraContext(this._serviceDefinition.name, 'deleteTimeEntry', id.toString())
803799
);
804800

805801
return response.ok;
@@ -840,7 +836,7 @@ export class RedmineSyncedService implements SyncedService {
840836
return mappingsObjectsResult;
841837
}
842838

843-
handleResponseException(ex: any, functionInfo: string, extraContext?: any): void {
839+
handleResponseException(ex: any, extraContext: T2tErrorExtraContext): void {
844840
let context: ExtraContext[] = [];
845841
if (ex !== undefined) {
846842
context = [
@@ -853,23 +849,24 @@ export class RedmineSyncedService implements SyncedService {
853849
}
854850

855851
const error = this._errorService.createRedmineError(ex?.response?.error ?? ex);
856-
if (ex.response) {
857-
error.data = {
858-
status: ex.response.statusCode,
859-
errors: ex.response.body.errors,
860-
extraContext: extraContext ?? {}
861-
};
862-
}
852+
863853

864854
if (ex.response && (ex.response.statusCode === 401 || ex.response.statusCode === 403)) {
865855
error.specification += " - API key error";
856+
error.data = undefined;
857+
866858
} else if (ex.response) {
867-
const message = `${functionInfo} failed with a response code ${ex.response.statusCode}`;
859+
const message = `${extraContext.functionName} failed with a response code ${ex.response.statusCode}`;
868860
error.specification += " - " + message;
861+
extraContext.responseErrors = ex.response.body?.errors ?? [];
862+
error.data = extraContext;
863+
869864
this._sentryService.logRedmineError(this._projectsUri, message, context);
870865
} else {
871-
const message = `${functionInfo} failed without a response`;
866+
const message = `${extraContext.functionName} failed without a response`;
872867
error.specification += " - " + message;
868+
error.data = extraContext;
869+
873870
this._sentryService.logRedmineError(this._projectsUri, message, context);
874871
}
875872

@@ -894,7 +891,7 @@ export class RedmineSyncedService implements SyncedService {
894891
.accept('application/json')
895892
.type('application/json')
896893
.set('X-Redmine-API-Key', this._serviceDefinition.apiKey),
897-
'getServiceObjects'
894+
new T2tErrorExtraContext(this._serviceDefinition.name, 'getServiceObjects')
898895
);
899896
responseIssues.body?.issues.forEach((issue: never) => {
900897
issues.push(

src/synced_services/synced_service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface SyncedService {
6464
*/
6565
updateServiceObject(objectId: string | number, serviceObject: ServiceObject): Promise<ServiceObject>;
6666

67-
deleteServiceObject(id: string | number, objectType: string): Promise<boolean>;
67+
deleteServiceObject(id: string | number, objectType: string, name: string): Promise<boolean>;
6868

6969
/**
7070
* Generates full name for given service object (Toggl, for example, generates names for tags as 'name (type)' or if issue, then '#id name (type)')

0 commit comments

Comments
 (0)