Skip to content

Commit

Permalink
[ENG-1438] Throw helpful error message when konfig.yaml is not config…
Browse files Browse the repository at this point in the history
…ured correctly when revalidating portal (#390)

* FileNotFoundError

* docs(changeset): improve error messaging when file not found from github
  • Loading branch information
dphuang2 authored Nov 23, 2023
1 parent e1cc90b commit 9c59eb3
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 78 deletions.
5 changes: 5 additions & 0 deletions generator/konfig-dash/.changeset/nice-dancers-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'konfig-cli': minor
---

improve error messaging when file not found from github
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CliUx, Command, Flags } from '@oclif/core'
import axios from 'axios'
import axios, { AxiosError } from 'axios'

function getRevalidatePortalUrl({ dev }: { dev: boolean }) {
if (dev) return 'http://127.0.0.1:3000/api/revalidate-portal'
Expand Down Expand Up @@ -41,21 +41,29 @@ export default class RevalidatePortal extends Command {
CliUx.ux.action.start(
`Revalidating portal for "${flags.owner}/${flags.repository}"`
)
const result = await axios.post(url, {
owner: flags.owner,
repo: flags.repository,
})
if (result.data['revalidated']) {
CliUx.ux.action.stop()
this.log(
`✅ Successfully revalidated portal at ${flags.owner}/${flags.repository}`
)
this.debug('Paths Revalidated:')
this.debug(result.data['revalidated'].join('\n'))
} else {
this.error(
`Failed to revalidate ${flags.organizationId}/${flags.portalId}: "${result.data}"`
)
try {
const result = await axios.post(url, {
owner: flags.owner,
repo: flags.repository,
})
if (result.data['revalidated']) {
CliUx.ux.action.stop()
this.log(
`✅ Successfully revalidated portal at ${flags.owner}/${flags.repository}`
)
this.debug('Paths Revalidated:')
this.debug(result.data['revalidated'].join('\n'))
} else {
this.error(
`Failed to revalidate ${flags.organizationId}/${flags.portalId}: "${result.data}"`
)
}
} catch (e) {
if (e instanceof AxiosError) {
if (typeof e.response?.data === 'string')
CliUx.ux.error(e.response?.data)
}
throw e
}
}
}
120 changes: 64 additions & 56 deletions generator/konfig-next-app/src/pages/api/revalidate-portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { githubGetKonfigYamls } from '@/utils/github-get-konfig-yamls'
import { createOctokitInstance } from '@/utils/octokit'
import { collectAllDocuments } from '@/utils/collect-all-documents'
import { findDomainsForOwnerAndRepo } from '@/utils/find-domains-for-owner-and-repo'
import { FileNotFoundError } from '@/utils/github-get-file-content'

const requestBodySchema = z.object({
owner: z.string(),
Expand Down Expand Up @@ -35,78 +36,85 @@ export default async function handler(
]),
]

// revalidate reference page
const { navbarData } = await githubGetReferenceResources({ owner, repo })
navbarData.forEach(({ links }) => {
links.forEach(({ link }) => {
toRevalidate.push(link)
try {
// revalidate reference page
const { navbarData } = await githubGetReferenceResources({ owner, repo })
navbarData.forEach(({ links }) => {
links.forEach(({ link }) => {
toRevalidate.push(link)
})
})
})
const { navbarData: navbarDataWithoutOwnerAndRepo } =
await githubGetReferenceResources({ owner, repo, omitOwnerAndRepo: true })
navbarDataWithoutOwnerAndRepo.forEach(({ links }) => {
links.forEach(({ link }) => {
for (const domain of domains) {
toRevalidate.push(`/${domain}${link}`)
}
const { navbarData: navbarDataWithoutOwnerAndRepo } =
await githubGetReferenceResources({ owner, repo, omitOwnerAndRepo: true })
navbarDataWithoutOwnerAndRepo.forEach(({ links }) => {
links.forEach(({ link }) => {
for (const domain of domains) {
toRevalidate.push(`/${domain}${link}`)
}
})
})
})

const demos = await generateDemosDataFromGithub({
orgId: owner,
portalId: repo,
})
const demos = await generateDemosDataFromGithub({
orgId: owner,
portalId: repo,
})

if (demos.result !== 'error') {
for (const demo of demos.portal.demos) {
const oldDemoPath = `/${owner}/${repo}/${demo.id}`
const newDemoPath = `/${owner}/${repo}/demo/${demo.id}`
toRevalidate.push(oldDemoPath)
toRevalidate.push(newDemoPath)
if (demos.result !== 'error') {
for (const demo of demos.portal.demos) {
const oldDemoPath = `/${owner}/${repo}/${demo.id}`
const newDemoPath = `/${owner}/${repo}/demo/${demo.id}`
toRevalidate.push(oldDemoPath)
toRevalidate.push(newDemoPath)

for (const domain of domains) {
const newDomainPath = `/${domain}/demo/${demo.id}`
toRevalidate.push(newDomainPath)
for (const domain of domains) {
const newDomainPath = `/${domain}/demo/${demo.id}`
toRevalidate.push(newDomainPath)
}
}
}
}

const octokit = await createOctokitInstance({ owner, repo })
const konfigYamls = await githubGetKonfigYamls({ owner, repo, octokit })
if (konfigYamls !== null) {
for (const konfigYaml of konfigYamls) {
if (konfigYaml.content.portal?.documentation !== undefined) {
const links = collectAllDocuments({
docConfig: konfigYaml.content.portal.documentation,
})
for (const link of links) {
toRevalidate.push(`/${owner}/${repo}/docs/${link.id}`)
for (const domain of domains) {
toRevalidate.push(`/${domain}/docs/${link.id}`)
const octokit = await createOctokitInstance({ owner, repo })
const konfigYamls = await githubGetKonfigYamls({ owner, repo, octokit })
if (konfigYamls !== null) {
for (const konfigYaml of konfigYamls) {
if (konfigYaml.content.portal?.documentation !== undefined) {
const links = collectAllDocuments({
docConfig: konfigYaml.content.portal.documentation,
})
for (const link of links) {
toRevalidate.push(`/${owner}/${repo}/docs/${link.id}`)
for (const domain of domains) {
toRevalidate.push(`/${domain}/docs/${link.id}`)
}
}
}
}
}
}

const revalidated: string[] = []
const revalidated: string[] = []

for (const path of toRevalidate) {
try {
await res.revalidate(path, { unstable_onlyGenerated: true })
revalidated.push(path)
} catch (e) {
if (e instanceof Error) {
if (e.message.includes('404')) {
console.log(`Tried to revalidate ${path} but got 404`)
continue
for (const path of toRevalidate) {
try {
await res.revalidate(path, { unstable_onlyGenerated: true })
revalidated.push(path)
} catch (e) {
if (e instanceof Error) {
if (e.message.includes('404')) {
console.log(`Tried to revalidate ${path} but got 404`)
continue
}
}
throw e
}
throw e
}
}

return res.json({
revalidated,
})
return res.json({
revalidated,
})
} catch (e) {
if (e instanceof FileNotFoundError) {
return res.status(404).send(e.message)
}
throw e
}
}
41 changes: 35 additions & 6 deletions generator/konfig-next-app/src/utils/github-get-file-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,32 @@ function computeCacheKey({
return `${owner}/${repo}/${path}`
}

export class FileNotFoundError extends Error {
innerError: Error
name = 'FileNotFoundError'

constructor(innerError: Error) {
let message =
"Make sure you've configured 'konfig.yaml' to point to the correct files."
if (
'response' in innerError &&
typeof innerError?.response === 'object' &&
innerError?.response !== null &&
'url' in innerError?.response &&
typeof innerError.response?.url === 'string'
) {
// parse "https://api.github.com/repos/passiv/snaptrade-sdks/contents/docs%2Frecommended-functionality.md" for "docs/recommended-functionality.md"
const path = innerError.response.url
.split('repos/')[1]
.split('/contents/')[1]
const decoded = decodeURIComponent(path)
message += ` Could not find file: "${decoded}"`
}
super(message)
this.innerError = innerError
}
}

export async function githubGetFileContent({
octokit,
owner,
Expand Down Expand Up @@ -62,11 +88,14 @@ export async function githubGetFileContent({
} else {
throw new Error('The specified path does not point to a file')
}
} catch (error) {
if (error instanceof Error)
console.error(
`Error occurred while getting file content: ${error.message}`
)
throw error
} catch (e) {
if (e instanceof Error) {
if ('status' in e && e.status === 404) {
throw new FileNotFoundError(e)
} else {
console.error(`Error occurred while getting file content: ${e.message}`)
}
}
throw e
}
}

0 comments on commit 9c59eb3

Please sign in to comment.