@financial-times/cp-content-pipeline-schema 2.14.0 → 2.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import type {
7
7
  import conceptIds from '@financial-times/n-concept-ids'
8
8
  import metadata from '@financial-times/n-display-metadata'
9
9
  import cloneDeep from 'clone-deep'
10
- import { OperationalError } from '@dotcom-reliability-kit/errors'
10
+ import { BaseError, OperationalError } from '@dotcom-reliability-kit/errors'
11
11
 
12
12
  import type { QueryContext } from '..'
13
13
  import sortBy from 'lodash.sortby'
@@ -127,24 +127,28 @@ function flattenFormattedZodIssues(
127
127
  }
128
128
 
129
129
  function getContentType(
130
- content: { type?: string; types: string[] },
130
+ content: BaselineContent,
131
131
  validate?: true
132
132
  ): LiteralUnionScalarValues<typeof ContentType>
133
133
  function getContentType(
134
- content: { type?: string; types: string[] },
134
+ content: BaselineContent,
135
135
  validate: false
136
136
  ): LiteralUnionScalarValues<typeof ContentType> | string
137
- function getContentType(
138
- content: { type?: string; types: string[] },
139
- validate = true
140
- ) {
137
+ function getContentType(content: BaselineContent, validate = true) {
141
138
  const TYPE_REGEX = /https?:\/\/www.ft.com\/ontology\/content\//
142
139
  const useType =
143
140
  'type' in content && content.type ? content.type : content.types[0]
144
141
  const type = useType?.replace(TYPE_REGEX, '')
145
142
 
146
143
  if (validate && !validLiteralUnionValue(type, ContentType.values)) {
147
- throw new Error('Content type is invalid: ' + useType)
144
+ // if we get a request for a content type we can't (and shouldn't)
145
+ // handle, such as Image, there's nothing else we can do, so throw
146
+ throw new BaseError({
147
+ message: `Content type is invalid: ${useType}`,
148
+ code: 'UNEXPECTED_CONTENT_TYPE',
149
+ type: useType,
150
+ id: content.id,
151
+ })
148
152
  }
149
153
 
150
154
  return type
@@ -156,6 +160,8 @@ const baselineContentSchema = z.object({
156
160
  types: z.array(z.string()),
157
161
  })
158
162
 
163
+ type BaselineContent = z.infer<typeof baselineContentSchema>
164
+
159
165
  export class CapiResponse {
160
166
  constructor(
161
167
  private capiData: ContentTypeSchemas,
@@ -17,16 +17,25 @@ const resolvers = {
17
17
  try {
18
18
  return await context.dataSources.capi.getContent(args.uuid)
19
19
  } catch (error) {
20
- if (
21
- error instanceof BaseError &&
22
- error.data.upstreamStatusCode === 404
23
- ) {
24
- throw new HttpError({
25
- code: 'CONTENT_NOT_FOUND',
26
- message: `Content ${args.uuid} not found in Content API`,
27
- statusCode: 404,
28
- relatesToSystems: ['up-ica'],
29
- })
20
+ if (error instanceof BaseError) {
21
+ if (error.data.upstreamStatusCode === 404) {
22
+ throw new HttpError({
23
+ code: 'CONTENT_NOT_FOUND',
24
+ message: 'Content not found in Content API',
25
+ cause: error,
26
+ uuid: args.uuid,
27
+ statusCode: 404,
28
+ relatesToSystems: ['up-ica'],
29
+ })
30
+ }
31
+ if (error.code === 'UNEXPECTED_CONTENT_TYPE') {
32
+ throw new HttpError({
33
+ code: error.code,
34
+ cause: error,
35
+ message: `Requested a content type we don't handle`,
36
+ statusCode: 404,
37
+ })
38
+ }
30
39
  }
31
40
 
32
41
  throw error