diff --git a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts index 91da19224d83c..954086ee53084 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts @@ -69,7 +69,6 @@ export async function getErrorSampleDetails({ const requiredFields = asMutableArray([ AGENT_NAME, PROCESSOR_EVENT, - TRACE_ID, TIMESTAMP_US, AT_TIMESTAMP, SERVICE_NAME, @@ -78,6 +77,7 @@ export async function getErrorSampleDetails({ ] as const); const optionalFields = asMutableArray([ + TRACE_ID, TRANSACTION_ID, SPAN_ID, AGENT_VERSION, @@ -131,7 +131,7 @@ export async function getErrorSampleDetails({ const errorFromFields = unflattenKnownApmEventFields(hit.fields, requiredFields); const transactionId = errorFromFields.transaction?.id ?? errorFromFields.span?.id; - const traceId = errorFromFields.trace.id; + const traceId = errorFromFields.trace?.id; let transaction: Transaction | undefined; if (transactionId && traceId) { diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/generate_data.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/generate_data.ts index ea22c866bd668..4859155239482 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/generate_data.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { ApmFields, apm, timerange } from '@kbn/apm-synthtrace-client'; import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; export const config = { @@ -25,11 +25,13 @@ export async function generateData({ serviceName, start, end, + overrides, }: { apmSynthtraceEsClient: ApmSynthtraceEsClient; serviceName: string; start: number; end: number; + overrides?: Partial; }) { const serviceGoProdInstance = apm .service({ name: serviceName, environment: 'production', agentName: 'go' }) @@ -40,18 +42,18 @@ export async function generateData({ const documents = [appleTransaction, bananaTransaction].flatMap((transaction, index) => { return [ - interval - .rate(transaction.successRate) - .generator((timestamp) => - serviceGoProdInstance - .transaction({ transactionName: transaction.name }) - .timestamp(timestamp) - .duration(1000) - .success() - ), + interval.rate(transaction.successRate).generator((timestamp) => + serviceGoProdInstance + .transaction({ transactionName: transaction.name }) + .overrides(overrides ? overrides : {}) + .timestamp(timestamp) + .duration(1000) + .success() + ), interval.rate(transaction.failureRate).generator((timestamp) => serviceGoProdInstance .transaction({ transactionName: transaction.name }) + .overrides(overrides ? overrides : {}) .errors( serviceGoProdInstance .error({ message: `Error ${index}`, type: transaction.name }) diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/group_id_samples.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/group_id_samples.spec.ts index 9c20c97fde868..764a5a9bcb4b1 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/group_id_samples.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/errors/group_id_samples.spec.ts @@ -136,6 +136,33 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon }); }); + describe('error sample without trace.id', () => { + before(async () => { + await generateData({ + serviceName, + start, + end, + apmSynthtraceEsClient, + overrides: { + 'trace.id': undefined, + }, + }); + }); + + after(() => apmSynthtraceEsClient.clean()); + + it('returns 200', async () => { + const errorsSamplesResponse = await callErrorGroupSamplesApi({ + groupId: '0000000000000000000000000Error 1', + }); + + const errorId = errorsSamplesResponse.body.errorSampleIds[0]; + + const response = await callErrorSampleDetailsApi(errorId); + expect(response.status).to.be(200); + }); + }); + describe('with sampled and unsampled transactions', () => { let errorGroupSamplesResponse: ErrorGroupSamples;