From c908176346f8f70727f2ae9557294f72bf249894 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Wed, 2 Oct 2024 09:19:55 +0200 Subject: [PATCH] feat: improved error handling --- .vscode/launch.json | 6 +++--- src/commands/login/actions.ts | 14 +++++++++++--- src/commands/login/index.ts | 4 ++-- src/constants.ts | 12 ++++++------ src/index.ts | 10 +++++++++- src/utils/index.ts | 11 +++++++++++ src/utils/konsola.test.ts | 3 ++- src/utils/konsola.ts | 2 +- 8 files changed, 45 insertions(+), 17 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 56ba92c..cd2fa55 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -22,9 +22,9 @@ { "type": "node", "request": "launch", - "name": "Debug pull-components", - "program": "${workspaceFolder}/dist/cli.mjs", - "args": ["push-components", "components.295017.json", "--space", "295018"], + "name": "Debug login", + "program": "${workspaceFolder}/dist/index.mjs", + "args": ["login", "--token", "295018"], "cwd": "${workspaceFolder}", "console": "integratedTerminal", "sourceMaps": true, diff --git a/src/commands/login/actions.ts b/src/commands/login/actions.ts index ef78a58..02b7ca9 100644 --- a/src/commands/login/actions.ts +++ b/src/commands/login/actions.ts @@ -1,5 +1,8 @@ +import chalk from 'chalk' import { regionsDomain } from '../../constants' +import type { FetchError } from 'ofetch' import { ofetch } from 'ofetch' +import { maskToken } from '../../utils' export const loginWithToken = async (token: string, region: string) => { try { @@ -10,7 +13,12 @@ export const loginWithToken = async (token: string, region: string) => { }) } catch (error) { - throw new Error('Error logging with token', error) + if ((error as FetchError).response?.status === 401) { + throw new Error(`The token provided ${chalk.bold(maskToken(token))} is invalid: ${chalk.bold(`401 ${(error as FetchError).data.error}`)} + + Please make sure you are using the correct token and try again.`) + } + throw new Error('Error logging with token', error as Error) } } @@ -22,7 +30,7 @@ export const loginWithEmailAndPassword = async (email: string, password: string, }) } catch (error) { - throw new Error('Error logging in with email and password', error) + throw new Error('Error logging in with email and password', error as Error) } } @@ -34,6 +42,6 @@ export const loginWithOtp = async (email: string, password: string, otp: string, }) } catch (error) { - throw new Error('Error logging in with email, password and otp', error) + throw new Error('Error logging in with email, password and otp', error as Error) } } diff --git a/src/commands/login/index.ts b/src/commands/login/index.ts index 3d487d0..4bd25ce 100644 --- a/src/commands/login/index.ts +++ b/src/commands/login/index.ts @@ -53,7 +53,7 @@ export const loginCommand = program konsola.ok(`Successfully logged in with token`) } catch (error) { - handleError(error as Error) + handleError(error as Error, true) } } else { @@ -123,7 +123,7 @@ export const loginCommand = program } } catch (error) { - handleError(error as Error) + handleError(error as Error, true) } } }) diff --git a/src/constants.ts b/src/constants.ts index deb1133..d30f772 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,8 +1,8 @@ -export const commands = { +export const commands: Record = { LOGIN: 'login', } -export const regions = { +export const regions: Record = { EU: 'eu', US: 'us', CN: 'cn', @@ -10,7 +10,7 @@ export const regions = { AP: 'ap', } -export const regionsDomain = { +export const regionsDomain: Record = { eu: 'api.storyblok.com', us: 'api-us.storyblok.com', cn: 'app.storyblokchina.cn', @@ -18,7 +18,7 @@ export const regionsDomain = { ap: 'api-ap.storyblok.com', } -export const managementApiRegions = { +export const managementApiRegions: Record = { eu: 'mapi.storyblok.com', us: 'mapi-us.storyblok.com', cn: 'mapi.storyblokchina.cn', @@ -26,7 +26,7 @@ export const managementApiRegions = { ap: 'mapi-ap.storyblok.com', } -export const regionNames = { +export const regionNames: Record = { eu: 'Europe', us: 'United States', cn: 'China', @@ -34,7 +34,7 @@ export const regionNames = { ap: 'Australia', } -export const DEFAULT_AGENT = { +export const DEFAULT_AGENT: Record = { SB_Agent: 'SB-CLI', SB_Agent_Version: process.env.npm_package_version || '4.x', } diff --git a/src/index.ts b/src/index.ts index d1e7a10..7d91204 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ import './commands/login' const program = getProgram() console.clear() const introText = chalk.bgHex('#45bfb9').bold.black(` Storyblok CLI `) -const messageText = ` Starting Blok machine... ` +const messageText = ` ` console.log(formatHeader(` ${introText} ${messageText}`)) @@ -18,6 +18,14 @@ program.on('command:*', () => { program.help() }) +/* console.log(` +${chalk.hex('#45bfb9')(' ─────╮')} +${chalk.hex('#45bfb9')('│ │')} +${chalk.hex('#45bfb9')('│')} ◠ ◡ ◠ +${chalk.hex('#45bfb9')('|_ __|')} +${chalk.hex('#45bfb9')(' |/ ')} +`) */ + try { program.parse(process.argv) } diff --git a/src/utils/index.ts b/src/utils/index.ts index ebecde4..f8a74de 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -10,3 +10,14 @@ export const __dirname = dirname(__filename) export function isRegion(value: string): value is keyof typeof regions { return Object.values(regions).includes(value) } + +export function maskToken(token: string): string { + // Show only the first 4 characters and replace the rest with asterisks + if (token.length <= 4) { + // If the token is too short, just return it as is + return token + } + const visiblePart = token.slice(0, 4) + const maskedPart = '*'.repeat(token.length - 4) + return `${visiblePart}${maskedPart}` +} diff --git a/src/utils/konsola.test.ts b/src/utils/konsola.test.ts index d51f68b..36d9017 100644 --- a/src/utils/konsola.test.ts +++ b/src/utils/konsola.test.ts @@ -24,7 +24,8 @@ describe('konsola', () => { const consoleSpy = vi.spyOn(console, 'error') konsola.error(new Error('Oh gosh, this is embarrasing')) - expect(consoleSpy).toHaveBeenCalledWith(chalk.red(`Oh gosh, this is embarrasing`)) + const errorText = `${chalk.red('x')} Oh gosh, this is embarrasing` + expect(consoleSpy).toHaveBeenCalledWith(errorText) }) it('should prompt an error message with header', () => { diff --git a/src/utils/konsola.ts b/src/utils/konsola.ts index ad899ff..a0db1eb 100644 --- a/src/utils/konsola.ts +++ b/src/utils/konsola.ts @@ -23,7 +23,7 @@ export const konsola = { console.error(formatHeader(errorHeader)) } - console.error(chalk.red(err.message || err)) + console.error(`${chalk.red('x')} ${err.message || err}`) console.log('') // Add a line break }, }