@@ -64,13 +64,17 @@ function resolveErrorSummary(status: number): string {
6464}
6565
6666function resolveErrorDetail ( problem : ProblemDetails , status : number ) : string {
67+ const validationSummary = extractValidationSummary ( problem . errors ) ;
68+ if ( status === 400 && validationSummary ) {
69+ return validationSummary ;
70+ }
71+
6772 if ( problem . detail && problem . detail . trim ( ) . length > 0 ) {
6873 return problem . detail ;
6974 }
7075
71- const firstValidationError = extractFirstValidationError ( problem . errors ) ;
72- if ( firstValidationError ) {
73- return firstValidationError ;
76+ if ( validationSummary ) {
77+ return validationSummary ;
7478 }
7579
7680 switch ( status ) {
@@ -89,16 +93,62 @@ function resolveErrorDetail(problem: ProblemDetails, status: number): string {
8993 }
9094}
9195
92- function extractFirstValidationError ( errors ?: Record < string , string [ ] > ) : string | null {
96+ function extractValidationSummary ( errors ?: Record < string , string [ ] > ) : string | null {
9397 if ( ! errors ) {
9498 return null ;
9599 }
96100
97- for ( const messages of Object . values ( errors ) ) {
98- if ( messages . length > 0 ) {
99- return messages [ 0 ] ;
101+ const messages : string [ ] = [ ] ;
102+
103+ for ( const [ fieldName , fieldErrors ] of Object . entries ( errors ) ) {
104+ for ( const message of fieldErrors ) {
105+ if ( ! message || message . trim ( ) . length === 0 ) {
106+ continue ;
107+ }
108+
109+ const fieldLabel = toFieldLabel ( fieldName ) ;
110+ const hasFieldNameInMessage = message . toLowerCase ( ) . includes ( fieldLabel . toLowerCase ( ) ) ;
111+ messages . push ( hasFieldNameInMessage ? message : `${ fieldLabel } : ${ message } ` ) ;
100112 }
101113 }
102114
103- return null ;
115+ if ( messages . length === 0 ) {
116+ return null ;
117+ }
118+
119+ const preview = messages . slice ( 0 , 2 ) . join ( ' ' ) ;
120+ const remainingCount = messages . length - 2 ;
121+ if ( remainingCount > 0 ) {
122+ return `${ preview } (+${ remainingCount } more)` ;
123+ }
124+
125+ return preview ;
126+ }
127+
128+ function toFieldLabel ( fieldName : string ) : string {
129+ const normalized = fieldName
130+ . replace ( / ^ \$ \. / , '' )
131+ . replace ( / \. / g, ' ' )
132+ . replace ( / ( [ a - z 0 - 9 ] ) ( [ A - Z ] ) / g, '$1 $2' )
133+ . replace ( / \s + / g, ' ' )
134+ . trim ( ) ;
135+
136+ if ( ! normalized ) {
137+ return 'Field' ;
138+ }
139+
140+ return normalized
141+ . split ( ' ' )
142+ . map ( ( segment ) => {
143+ if ( segment . length === 0 ) {
144+ return segment ;
145+ }
146+
147+ if ( segment . length === 1 ) {
148+ return segment . toUpperCase ( ) ;
149+ }
150+
151+ return `${ segment [ 0 ] . toUpperCase ( ) } ${ segment . slice ( 1 ) } ` ;
152+ } )
153+ . join ( ' ' ) ;
104154}
0 commit comments