diff --git a/node-src/lib/upload.ts b/node-src/lib/upload.ts index 51bebdabf..f5ad83571 100644 --- a/node-src/lib/upload.ts +++ b/node-src/lib/upload.ts @@ -2,6 +2,8 @@ import makeZipFile from './compress'; import { Context, FileDesc, TargetInfo } from '../types'; import { uploadZip, waitForUnpack } from './uploadZip'; import { uploadFiles } from './uploadFiles'; +import { maxFileCountExceeded } from '../ui/messages/errors/maxFileCountExceeded'; +import { maxFileSizeExceeded } from '../ui/messages/errors/maxFileSizeExceeded'; const UploadBuildMutation = ` mutation UploadBuildMutation($buildId: ObjID!, $files: [FileUploadInput!]!, $zip: Boolean) { @@ -24,6 +26,7 @@ const UploadBuildMutation = ` } } userErrors { + __typename ... on UserError { message } @@ -46,13 +49,24 @@ interface UploadBuildMutationResult { targets: TargetInfo[]; zipTarget?: TargetInfo & { sentinelUrl: string }; }; - userErrors: { - message: string; - maxFileCount?: number; - maxFileSize?: number; - fileCount?: number; - filePaths?: string[]; - }[]; + userErrors: ( + | { + __typename: 'UserError'; + message: string; + } + | { + __typename: 'MaxFileCountExceededError'; + message: string; + maxFileCount: number; + fileCount: number; + } + | { + __typename: 'MaxFileSizeExceededError'; + message: string; + maxFileSize: number; + filePaths: string[]; + } + )[]; }; } @@ -79,8 +93,16 @@ export async function uploadBuild( ); if (uploadBuild.userErrors.length) { - uploadBuild.userErrors.forEach((e) => ctx.log.error(e.message)); - return options.onError?.(new Error('Upload does not meet requirements')); + uploadBuild.userErrors.forEach((e) => { + if (e.__typename === 'MaxFileCountExceededError') { + ctx.log.error(maxFileCountExceeded(e)); + } else if (e.__typename === 'MaxFileSizeExceededError') { + ctx.log.error(maxFileSizeExceeded(e)); + } else { + ctx.log.error(e.message); + } + }); + return options.onError?.(new Error('Upload rejected due to user error')); } const targets = uploadBuild.info.targets.map((target) => { diff --git a/node-src/ui/messages/errors/maxFileCountExceeded.stories.ts b/node-src/ui/messages/errors/maxFileCountExceeded.stories.ts new file mode 100644 index 000000000..41b67cade --- /dev/null +++ b/node-src/ui/messages/errors/maxFileCountExceeded.stories.ts @@ -0,0 +1,11 @@ +import { maxFileCountExceeded } from './maxFileCountExceeded'; + +export default { + title: 'CLI/Messages/Errors', +}; + +export const MaxFileCountExceeded = () => + maxFileCountExceeded({ + fileCount: 54_321, + maxFileCount: 20_000, + }); diff --git a/node-src/ui/messages/errors/maxFileCountExceeded.ts b/node-src/ui/messages/errors/maxFileCountExceeded.ts new file mode 100644 index 000000000..6487599c8 --- /dev/null +++ b/node-src/ui/messages/errors/maxFileCountExceeded.ts @@ -0,0 +1,19 @@ +import chalk from 'chalk'; +import { dedent } from 'ts-dedent'; + +import { error } from '../../components/icons'; + +export const maxFileCountExceeded = ({ + fileCount, + maxFileCount, +}: { + fileCount: number; + maxFileCount: number; +}) => + dedent(chalk` + ${error} {bold Attempted to upload too many files} + You're not allowed to upload more than ${maxFileCount} files per build. + Your Storybook contains ${fileCount} files. This is a very high number. + Do you have files in a static/public directory that shouldn't be there? + Contact customer support if you need to increase this limit. + `); diff --git a/node-src/ui/messages/errors/maxFileSizeExceeded.stories.ts b/node-src/ui/messages/errors/maxFileSizeExceeded.stories.ts new file mode 100644 index 000000000..a7cb75430 --- /dev/null +++ b/node-src/ui/messages/errors/maxFileSizeExceeded.stories.ts @@ -0,0 +1,8 @@ +import { maxFileSizeExceeded } from './maxFileSizeExceeded'; + +export default { + title: 'CLI/Messages/Errors', +}; + +export const MaxFileSizeExceeded = () => + maxFileSizeExceeded({ filePaths: ['index.js', 'main.js'], maxFileSize: 12345 }); diff --git a/node-src/ui/messages/errors/maxFileSizeExceeded.ts b/node-src/ui/messages/errors/maxFileSizeExceeded.ts new file mode 100644 index 000000000..6e619607e --- /dev/null +++ b/node-src/ui/messages/errors/maxFileSizeExceeded.ts @@ -0,0 +1,18 @@ +import chalk from 'chalk'; +import { dedent } from 'ts-dedent'; + +import { error } from '../../components/icons'; + +export const maxFileSizeExceeded = ({ + filePaths, + maxFileSize, +}: { + filePaths: string[]; + maxFileSize: number; +}) => + dedent(chalk` + ${error} {bold Attempted to exceed maximum file size} + You're attempting to upload files that exceed the maximum file size of ${maxFileSize} bytes. + Contact customer support if you need to increase this limit. + - ${filePaths.map((path) => path).join('\n- ')} + `);