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;
}