1
0
mirror of synced 2026-01-10 00:03:04 -05:00

Fix openapi parser bug and add error throwing (#48845)

This commit is contained in:
Rachael Sewell
2024-01-24 16:50:22 -08:00
committed by GitHub
parent 828033f0c9
commit 4e2658cdfa
3 changed files with 86 additions and 50 deletions

View File

@@ -101,7 +101,7 @@ export async function getBodyParams(schema, topLevel = false) {
}
keyParam.childParamsGroups.push(...(await getBodyParams(param.additionalProperties, false)))
childParamsGroups.push(keyParam)
} else if (paramType && paramType.includes('array')) {
} else if (paramType && paramType.includes('array') && param.items) {
if (param.items && param.items.oneOf) {
if (param.items.oneOf.every((object) => object.type === 'object')) {
paramType.splice(paramType.indexOf('array'), 1, `array of objects`)

View File

@@ -67,18 +67,28 @@ export default class Operation {
}
async renderDescription() {
this.descriptionHTML = await renderContent(this.#operation.description)
return this
try {
this.descriptionHTML = await renderContent(this.#operation.description)
return this
} catch (error) {
console.error(error)
throw new Error(`Error rendering description for ${this.verb} ${this.requestPath}`)
}
}
async codeExamples() {
this.codeExamples = await getCodeSamples(this.#operation)
return await Promise.all(
this.codeExamples.map(async (codeExample) => {
codeExample.response.description = await renderContent(codeExample.response.description)
return codeExample
}),
)
try {
return await Promise.all(
this.codeExamples.map(async (codeExample) => {
codeExample.response.description = await renderContent(codeExample.response.description)
return codeExample
}),
)
} catch (error) {
console.error(error)
throw new Error(`Error generating code examples for ${this.verb} ${this.requestPath}`)
}
}
async renderStatusCodes() {
@@ -86,38 +96,49 @@ export default class Operation {
const responseKeys = Object.keys(responses)
if (responseKeys.length === 0) return []
this.statusCodes = await Promise.all(
responseKeys.map(async (responseCode) => {
const response = responses[responseCode]
const httpStatusCode = responseCode
const httpStatusMessage = httpStatusCodes.getMessage(Number(responseCode), 'HTTP/2')
// The OpenAPI should be updated to provide better descriptions, but
// until then, we can catch some known generic descriptions and replace
// them with the default http status message.
const responseDescription =
response.description.toLowerCase() === 'response'
? await renderContent(httpStatusMessage)
: await renderContent(response.description)
try {
this.statusCodes = await Promise.all(
responseKeys.map(async (responseCode) => {
const response = responses[responseCode]
const httpStatusCode = responseCode
const httpStatusMessage = httpStatusCodes.getMessage(Number(responseCode), 'HTTP/2')
// The OpenAPI should be updated to provide better descriptions, but
// until then, we can catch some known generic descriptions and replace
// them with the default http status message.
const responseDescription =
response.description.toLowerCase() === 'response'
? await renderContent(httpStatusMessage)
: await renderContent(response.description)
return {
httpStatusCode,
description: responseDescription,
}
}),
)
return {
httpStatusCode,
description: responseDescription,
}
}),
)
} catch (error) {
console.error(error)
throw new Error(`Error rendering status codes for ${this.verb} ${this.requestPath}`)
}
}
async renderParameterDescriptions() {
return Promise.all(
this.parameters.map(async (param) => {
param.description = await renderContent(param.description)
return param
}),
)
try {
return Promise.all(
this.parameters.map(async (param) => {
param.description = await renderContent(param.description)
return param
}),
)
} catch (error) {
console.error(error)
throw new Error(`Error rendering parameter descriptions for ${this.verb} ${this.requestPath}`)
}
}
async renderBodyParameterDescriptions() {
if (!this.#operation.requestBody) return []
// There is currently only one operation with more than one content type
// and the request body parameter types are the same for both.
// Operation Id: markdown/render-raw
@@ -129,26 +150,40 @@ export default class Operation {
}
// Merges any instances of allOf in the schema using a deep merge
const mergedAllofSchema = mergeAllOf(schema)
this.bodyParameters = isPlainObject(schema) ? await getBodyParams(mergedAllofSchema, true) : []
try {
this.bodyParameters = isPlainObject(schema)
? await getBodyParams(mergedAllofSchema, true)
: []
} catch (error) {
console.error(error)
throw new Error(
`Error rendering body parameter descriptions for ${this.verb} ${this.requestPath}`,
)
}
}
async renderPreviewNotes() {
const previews = get(this.#operation, 'x-github.previews', [])
this.previews = await Promise.all(
previews.map(async (preview) => {
const note = preview.note
// remove extra leading and trailing newlines
.replace(/```\n\n\n/gm, '```\n')
.replace(/```\n\n/gm, '```\n')
.replace(/\n\n\n```/gm, '\n```')
.replace(/\n\n```/gm, '\n```')
try {
this.previews = await Promise.all(
previews.map(async (preview) => {
const note = preview.note
// remove extra leading and trailing newlines
.replace(/```\n\n\n/gm, '```\n')
.replace(/```\n\n/gm, '```\n')
.replace(/\n\n\n```/gm, '\n```')
.replace(/\n\n```/gm, '\n```')
// convert single-backtick code snippets to fully fenced triple-backtick blocks
// example: This is the description.\n\n`application/vnd.github.machine-man-preview+json`
.replace(/\n`application/, '\n```\napplication')
.replace(/json`$/, 'json\n```')
return await renderContent(note)
}),
)
// convert single-backtick code snippets to fully fenced triple-backtick blocks
// example: This is the description.\n\n`application/vnd.github.machine-man-preview+json`
.replace(/\n`application/, '\n```\napplication')
.replace(/json`$/, 'json\n```')
return await renderContent(note)
}),
)
} catch (error) {
console.error(error)
throw new Error(`Error rendering preview notes for ${this.verb} ${this.requestPath}`)
}
}
}

View File

@@ -23,12 +23,13 @@ export async function syncRestData(sourceDirectory, restSchemas) {
const operations = []
try {
console.log('Proccessing operations for version ', schemaName)
const newOperations = await createOperations(schema)
operations.push(...newOperations)
await processOperations(operations)
} catch (error) {
throw new Error(
"🐛 Whoops! It looks like the script wasn't able to parse the dereferenced schema. A recent change may not yet be supported by the decorator. Please reach out in the #docs-engineering slack channel for help.",
`${error}\n\n🐛 Whoops! It looks like the script wasn't able to parse the dereferenced schema. A recent change may not yet be supported by the decorator. Please reach out in the #docs-engineering slack channel for help.`,
)
}
const formattedOperations = await formatRestData(operations)