Skip to content

Commit

Permalink
feat: attributes (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbyg603 authored Apr 4, 2024
1 parent 264daf2 commit f2cf741
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 37 deletions.
1 change: 1 addition & 0 deletions spec/fakes/crash/crash-api-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const createFakeCrashApiResponse = () => ({
appKey: 'ardvark',
appName: 'boregard',
appVersion: '1.2.3.4',
attributes: '{ "key": "value"}',
comments: 'blah blah blah',
crashTime: '2023-02-04T17:58:15+0000Z',
defectLabel: 'weee!',
Expand Down
11 changes: 11 additions & 0 deletions src/common/parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function safeParseJson(json: string | undefined): Record<string, unknown> {
if (!json) {
return {};
}

try {
return JSON.parse(json);
} catch {
return {};
}
}
8 changes: 5 additions & 3 deletions src/crash/crash-details/crash-details.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ describe('createCrashDetails', () => {

const result = createCrashDetails(options);

expect(result).toEqual({
...options,
const { attributes, ...rest } = options;
expect(result).toEqual(jasmine.objectContaining({
...rest,
attributes: JSON.parse(attributes),
events: createEvents(options.events),
additionalInfo: jasmine.any(AdditionalInfo),
});
}));
});

it('should default comments and description to empty string if null', () => {
Expand Down
72 changes: 38 additions & 34 deletions src/crash/crash-details/crash-details.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AdditionalInfo, GroupableThreadCollection, ThreadCollection } from '@crash';
import { Event } from '@events';
import ac from 'argument-contracts';
import { createEvents, EventResponseObject } from '../../events/events-api-client/event';
import { safeParseJson } from 'src/common/parse';
import { EventResponseObject, createEvents } from '../../events/events-api-client/event';
import { AdditionalInfoResponseObject } from '../additional-info/additional-info';

export enum ProcessingStatus {
Expand All @@ -27,6 +28,7 @@ export interface CrashDetails {
appKey: string;
appName: string;
appVersion: string;
attributes: Record<string, unknown>;
comments: string;
crashTime: string;
defectTrackerType: DefectTrackerType;
Expand Down Expand Up @@ -64,10 +66,10 @@ export function createCrashDetails(options: CrashDetailsRawResponse): CrashDetai
ac.assertNumber(<number>options.stackKeyId, 'options.stackKeyId');
ac.assertBoolean(<boolean>options.missingSymbols, 'options.missingSymbols');

// TODO BG, the API should really guarantee reasonable defaults for these values
const appName = defaultToEmptyString(options.appName, 'options.appName');
const appVersion = defaultToEmptyString(options.appVersion, 'options.appVersion');
const appKey = defaultToEmptyString(options.appKey, 'options.appKey');
const attributes = safeParseJson(options.attributes);
const comments = defaultToEmptyString(options.comments, 'options.comments');
const crashTime = defaultToEmptyString(options.crashTime, 'options.crashTime');
const defectLabel = defaultToEmptyString(options.defectLabel, 'options.defectLabel');
Expand All @@ -81,7 +83,7 @@ export function createCrashDetails(options: CrashDetailsRawResponse): CrashDetai
const platform = defaultToEmptyString(options.platform, 'options.platform');
const processor = defaultToEmptyString(options.processor, 'options.processor');
const stackKey = defaultToEmptyString(options.stackKey, 'options.stackKey');
const stackKeyComment = defaultToEmptyString(options.stackKeyComment,'options.stackKeyComment');
const stackKeyComment = defaultToEmptyString(options.stackKeyComment, 'options.stackKeyComment');
const stackKeyDefectLabel = defaultToEmptyString(options.stackKeyDefectLabel, 'options.stackKeyDefectLabel');
const stackKeyDefectUrl = defaultToEmptyString(options.stackKeyDefectUrl, 'options.stackKeyDefectUrl');
const user = defaultToEmptyString(options.user, 'options.user');
Expand All @@ -92,51 +94,53 @@ export function createCrashDetails(options: CrashDetailsRawResponse): CrashDetai

const events = createEvents(options.events as EventResponseObject[]);
const thread = new GroupableThreadCollection({
...<ThreadCollection>options.thread,
stackKeyId: <number>options.stackKeyId,
...<ThreadCollection>options.thread,
stackKeyId: <number>options.stackKeyId,
});
const additionalInfo = AdditionalInfo.fromRawResponse(
options.debuggerOutput
options.debuggerOutput
);

return {
...options,
appKey,
appName,
appVersion,
comments,
crashTime,
defectLabel,
defectUrl,
description,
dumpfile,
email,
exceptionCode,
exceptionMessage,
ipAddress,
platform,
processor,
stackKey,
stackKeyComment,
stackKeyDefectLabel,
stackKeyDefectUrl,
user,
thread,
additionalInfo,
events,
...options,
appKey,
appName,
appVersion,
attributes,
comments,
crashTime,
defectLabel,
defectUrl,
description,
dumpfile,
email,
exceptionCode,
exceptionMessage,
ipAddress,
platform,
processor,
stackKey,
stackKeyComment,
stackKeyDefectLabel,
stackKeyDefectUrl,
user,
thread,
additionalInfo,
events,
} as CrashDetails;
}

export interface CrashDetailsRawResponse extends Partial<Omit<CrashDetails, 'events' | 'debuggerOutput'>> {
export interface CrashDetailsRawResponse extends Partial<Omit<CrashDetails, 'events' | 'debuggerOutput' | 'attributes'>> {
attributes?: string;
events?: Array<EventResponseObject>;
debuggerOutput?: AdditionalInfoResponseObject;
}

function defaultToEmptyString(value, name) {
if (value) {
ac.assertString(value, name);
return value;
ac.assertString(value, name);
return value;
} else {
return '';
return '';
}
}
6 changes: 6 additions & 0 deletions src/crashes/crashes-api-row/crashes-api-row.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { safeParseJson } from 'src/common/parse';

interface CrashData {
groupByCount: number;
stackKey: string;
Expand Down Expand Up @@ -26,6 +28,7 @@ interface CrashDataWithMappedProperties extends CrashData {
stackKeyId: number;
comments: string;
ipAddress: string;
attributes: Record<string, unknown>;
}

export interface CrashesApiResponseRow extends CrashData {
Expand All @@ -34,6 +37,7 @@ export interface CrashesApiResponseRow extends CrashData {
stackKeyId: string;
Comments: string;
IpAddress: string;
attributes?: string;
}

export enum CrashTypeId {
Expand Down Expand Up @@ -88,6 +92,7 @@ export class CrashesApiRow implements CrashDataWithMappedProperties {
skComments: string;
exceptionCode: string;
exceptionMessage: string;
attributes: Record<string, unknown>;

constructor(rawApiRow: CrashesApiResponseRow) {
this.id = Number(rawApiRow.id);
Expand All @@ -114,6 +119,7 @@ export class CrashesApiRow implements CrashDataWithMappedProperties {
this.skComments = rawApiRow.skComments;
this.exceptionCode = rawApiRow.exceptionCode;
this.exceptionMessage = rawApiRow.exceptionMessage;
this.attributes = safeParseJson(rawApiRow.attributes);

Object.freeze(this);
}
Expand Down

0 comments on commit f2cf741

Please sign in to comment.