1+ import { ErrorObject } from 'ajv' ;
2+ import chalk from 'chalk' ;
3+
4+ import { ResourceConfig } from '../entities/resource-config.js' ;
5+ import { SourceMapCache } from '../parser/source-maps.js' ;
6+ import { formatAjvErrors } from '../utils/ajv.js' ;
17import { RemoveErrorMethods } from './types.js' ;
28
3- export class InternalError extends Error {
9+ export abstract class CodifyError extends Error {
10+ abstract formattedMessage ( ) : string
11+ }
12+
13+ export class InternalError extends CodifyError {
414 name = 'InternalError'
15+
16+ formattedMessage ( ) : string {
17+ return `Internal error: ${ this . message } ` ;
18+ }
519}
620
21+ export class AjvValidationError extends CodifyError {
22+ validationErrors : ErrorObject [ ] ;
23+ sourceMapKey ?: string ;
24+ sourceMaps ?: SourceMapCache ;
25+
26+ constructor (
27+ message : string ,
28+ validationErrors : ErrorObject [ ] ,
29+ sourceMapKey ?: string ,
30+ sourceMaps ?: SourceMapCache ,
31+ ) {
32+ super ( message ) ;
33+ this . validationErrors = validationErrors ;
34+ this . sourceMapKey = sourceMapKey ;
35+ this . sourceMaps = sourceMaps ;
36+ }
737
8- export class SyntaxError extends Error {
9- name = 'ConfigFileSyntaxError'
38+ formattedMessage ( ) : string {
39+ let errorMessage = `Validation error: ${ this . message } .\n\n` ;
40+ errorMessage += formatAjvErrors ( this . validationErrors , this . sourceMapKey , this . sourceMaps )
41+ return errorMessage ;
42+ }
43+ }
1044
11- message ! : string ;
12- fileName ! : string ;
13- lineNumber ! : string ;
45+ export type PluginValidationErrorParams = Array < {
46+ customErrorMessage ?: string ,
47+ resource : ResourceConfig ,
48+ schemaErrors : ErrorObject [ ] ,
49+ } >
1450
15- constructor ( props : RemoveErrorMethods < SyntaxError > ) {
16- super ( props . message )
17- Object . assign ( this , props ) ;
51+ export class PluginValidationError extends CodifyError {
52+ resourceErrors : PluginValidationErrorParams
53+ sourceMaps ?: SourceMapCache
54+
55+ constructor (
56+ params : PluginValidationErrorParams ,
57+ sourceMaps ?: SourceMapCache ,
58+ ) {
59+ super ( 'Validation error: the following parameters are not supported.\n\n' ) ;
60+ this . resourceErrors = params
61+ this . sourceMaps = sourceMaps ;
62+ }
63+
64+ formattedMessage ( ) : string {
65+ let errorMessage = `${ this . message } ` ;
66+
67+ for ( const resourceError of this . resourceErrors ) {
68+ const { customErrorMessage, resource, schemaErrors } = resourceError ;
69+
70+ errorMessage += `Resource "${ resource . id } " has invalid parameters.\n`
71+ errorMessage += formatAjvErrors ( schemaErrors , resource . sourceMapKey , this . sourceMaps )
72+
73+ if ( customErrorMessage ) {
74+ let childMessage = `${ schemaErrors . length + 1 } . ${ customErrorMessage } \n`
75+
76+ if ( resource . sourceMapKey && this . sourceMaps ) {
77+ childMessage += `${ this . sourceMaps . getCodeSnippet ( resource . sourceMapKey ) } \n` ;
78+ }
79+
80+ errorMessage += childMessage . split ( / \n / )
81+ . map ( ( l ) => ` ${ l } ` )
82+ . join ( '\n' )
83+ }
84+ }
85+
86+ return errorMessage ;
87+ }
88+ }
89+
90+ export class TypeNotFoundError extends CodifyError {
91+ invalidConfigs : ResourceConfig [ ] ;
92+ sourceMaps ?: SourceMapCache ;
93+
94+ constructor ( invalidConfigs : ResourceConfig [ ] , sourceMaps ?: SourceMapCache ) {
95+ super ( 'Validation error: invalid type found. Resource type was not found in any plugins.' )
96+
97+ this . invalidConfigs = invalidConfigs ;
98+ this . sourceMaps = sourceMaps ;
99+ }
100+
101+ formattedMessage ( ) : string {
102+ let errorMessage = `${ this . message } \n\n`
103+
104+ for ( const invalidConfig of this . invalidConfigs ) {
105+ if ( ! invalidConfig . sourceMapKey || ! this . sourceMaps ) {
106+ errorMessage += `type ${ invalidConfig . type } is not valid.`
107+ continue ;
108+ }
109+
110+ const codeSnippet = this . sourceMaps ?. getCodeSnippet ( SourceMapCache . combineKeys ( invalidConfig . sourceMapKey ! , 'type' ) )
111+ errorMessage += `Type "${ invalidConfig . type } " is not valid\n${ codeSnippet } `
112+ }
113+
114+ return errorMessage ;
18115 }
19116}
20117
@@ -31,12 +128,28 @@ export class InvalidResourceError extends Error {
31128 }
32129}
33130
34- export class JsonFileParseError extends Error {
131+ export class SyntaxError extends CodifyError {
35132 name = 'JsonFileParseError'
36133 fileName ! : string ;
37134
38- constructor ( props : RemoveErrorMethods < JsonFileParseError > ) {
135+ constructor ( props : RemoveErrorMethods < SyntaxError > ) {
39136 super ( props . message )
40137 Object . assign ( this , props ) ;
41138 }
139+
140+ formattedMessage ( ) : string {
141+ return `Syntax error: found in codify.json: ${ this . message } `
142+ }
143+ }
144+
145+ export function prettyPrintError ( error : unknown ) : void {
146+ if ( error instanceof CodifyError ) {
147+ return console . error ( chalk . red ( error . formattedMessage ( ) ) ) ;
148+ }
149+
150+ if ( error instanceof Error ) {
151+ return console . error ( chalk . red ( error . message ) ) ;
152+ }
153+
154+ console . error ( chalk . red ( String ( error ) ) ) ;
42155}
0 commit comments