From 3b0cce00357bf3858144d414288347c7c74f1a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 24 Dec 2019 10:33:20 +0100 Subject: [PATCH] [APM] Transaction page throws unhandled exception if transactions doesn't have `http.request` (#53760) * Making http.request optional * changing unit test --- .../DetailView/index.test.tsx | 27 +++++++++++++++++++ .../ErrorGroupDetails/DetailView/index.tsx | 2 +- .../Summary/TransactionSummary.test.tsx | 18 +++++++++++-- .../shared/Summary/TransactionSummary.tsx | 2 +- .../Summary/__fixtures__/transactions.ts | 22 +++++++++++++++ .../apm/typings/es_schemas/raw/fields/Http.ts | 2 +- 6 files changed, 68 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx index af4c129d61b60..7fe1386ba6414 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx @@ -126,4 +126,31 @@ describe('DetailView', () => { expect(wrapper.exists()).toBe(true); expect(wrapper).toMatchSnapshot(); }); + + it('should render without http request info', () => { + const errorGroup = { + occurrencesCount: 10, + transaction: undefined, + error: { + timestamp: { + us: 0 + }, + http: { response: { status_code: 404 } }, + url: { full: 'myUrl' }, + service: { name: 'myService' }, + user: { id: 'myUserId' }, + error: { exception: { handled: true } }, + transaction: { id: 'myTransactionId', sampled: true } + } as any + }; + expect(() => + shallow( + + ) + ).not.toThrowError(); + }); }); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx index 879733685c5f7..29c5d3329d16b 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx @@ -81,7 +81,7 @@ export function DetailView({ errorGroup, urlParams, location }: Props) { const errorUrl = error.error.page?.url || error.url?.full; - const method = error.http?.request.method; + const method = error.http?.request?.method; const status = error.http?.response?.status_code; return ( diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx index 19f626187cdd1..80ecea3cf9b33 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx @@ -7,12 +7,26 @@ import { shallow } from 'enzyme'; import React from 'react'; import { TransactionSummary } from './TransactionSummary'; -import { Transaction } from '../../../../typings/es_schemas/ui/Transaction'; import * as exampleTransactions from './__fixtures__/transactions'; describe('TransactionSummary', () => { describe('render', () => { - const transaction: Transaction = exampleTransactions.httpOk; + const transaction = exampleTransactions.httpOk; + + const props = { + errorCount: 0, + totalDuration: 0, + transaction + }; + + it('renders', () => { + expect(() => + shallow() + ).not.toThrowError(); + }); + }); + describe('renders RUM transaction without request info', () => { + const transaction = exampleTransactions.httpRumOK; const props = { errorCount: 0, diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx index c24435d381008..8b7380a18edc3 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx @@ -28,7 +28,7 @@ const getTransactionResultSummaryItem = (transaction: Transaction) => { : transaction.url?.full; if (url) { - const method = transaction.http?.request.method; + const method = transaction.http?.request?.method; const status = transaction.http?.response?.status_code; return ; diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts b/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts index 59496dad16572..f4346e47f23c2 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts @@ -25,3 +25,25 @@ export const httpOk: Transaction = { duration: { us: 0 } } }; + +export const httpRumOK: Transaction = { + '@timestamp': '0', + agent: { name: 'rum-js', version: '0' }, + http: { + response: { status_code: 200 } + }, + processor: { event: 'transaction', name: 'transaction' }, + service: { name: 'testServiceName' }, + timestamp: { us: 0 }, + trace: { id: 'testTrace' }, + transaction: { + page: { + url: 'elastic.co' + }, + name: 'testTransaction', + id: 'testId', + sampled: false, + type: 'testType', + duration: { us: 0 } + } +}; diff --git a/x-pack/legacy/plugins/apm/typings/es_schemas/raw/fields/Http.ts b/x-pack/legacy/plugins/apm/typings/es_schemas/raw/fields/Http.ts index cb63499a98186..be54e66c3d01b 100644 --- a/x-pack/legacy/plugins/apm/typings/es_schemas/raw/fields/Http.ts +++ b/x-pack/legacy/plugins/apm/typings/es_schemas/raw/fields/Http.ts @@ -5,7 +5,7 @@ */ export interface Http { - request: { method: string; [key: string]: unknown }; + request?: { method: string; [key: string]: unknown }; response?: { status_code: number; [key: string]: unknown }; version?: string; }