@@ -37,13 +37,57 @@ export class CoinbaseError extends Error {
37
37
}
38
38
39
39
function parseErrorResponse ( responseText : string ) : Record < string , any > {
40
+ if ( ! responseText ) {
41
+ return {
42
+ error : 'Empty response' ,
43
+ originalResponse : responseText
44
+ } ;
45
+ }
46
+
40
47
try {
41
48
return JSON . parse ( responseText ) ;
42
- } catch {
43
- return { } ;
49
+ } catch ( error ) {
50
+ // Create a more informative error object for debugging
51
+ return {
52
+ error : 'Invalid JSON response' ,
53
+ message : error instanceof Error ? error . message : 'Unknown parsing error' ,
54
+ originalResponse : responseText . slice ( 0 , 200 ) // Include truncated response for debugging
55
+ } ;
44
56
}
45
57
}
46
58
59
+ // Sanitize error messages to prevent sensitive information exposure
60
+ function sanitizeErrorMessage ( message : string ) : string {
61
+ if ( typeof message !== 'string' ) return '' ;
62
+
63
+ // Remove potential sensitive patterns (API keys, tokens, credentials)
64
+ return message
65
+ . replace ( / ( [ A - Z a - z 0 - 9 + / ] { 32 , } ) / g, '[REDACTED]' )
66
+ . replace ( / k e y - [ a - z A - Z 0 - 9 ] { 32 , } / g, '[REDACTED]' )
67
+ . replace ( / s k - [ a - z A - Z 0 - 9 ] { 32 , } / g, '[REDACTED]' )
68
+ . replace ( / \b [ A - Z a - z 0 - 9 . _ % + - ] + @ [ A - Z a - z 0 - 9 . - ] + \. [ A - Z a - z ] { 2 , } \b / g, '[REDACTED_EMAIL]' ) ;
69
+ }
70
+
71
+ function sanitizeErrorDetails ( details : Record < string , any > ) : Record < string , any > {
72
+ if ( ! details || typeof details !== 'object' ) return { } ;
73
+
74
+ const sensitiveKeys = [ 'apiKey' , 'secret' , 'token' , 'password' , 'credential' , 'key' , 'auth' ] ;
75
+
76
+ return Object . entries ( details ) . reduce ( ( acc , [ key , value ] ) => {
77
+ // Check if the key contains any sensitive patterns
78
+ if ( sensitiveKeys . some ( k => key . toLowerCase ( ) . includes ( k ) ) ) {
79
+ acc [ key ] = '[REDACTED]' ;
80
+ } else if ( typeof value === 'object' && value !== null ) {
81
+ acc [ key ] = sanitizeErrorDetails ( value ) ;
82
+ } else if ( typeof value === 'string' ) {
83
+ acc [ key ] = sanitizeErrorMessage ( value ) ;
84
+ } else {
85
+ acc [ key ] = value ;
86
+ }
87
+ return acc ;
88
+ } , { } as Record < string , any > ) ;
89
+ }
90
+
47
91
function getErrorDetails ( response : Response , responseText : string ) : CoinbaseErrorDetails {
48
92
const parsedError = parseErrorResponse ( responseText ) ;
49
93
const status = response . status ;
@@ -77,8 +121,8 @@ function getErrorDetails(response: Response, responseText: string): CoinbaseErro
77
121
if ( status === 400 ) {
78
122
return {
79
123
type : CoinbaseErrorType . VALIDATION ,
80
- message : parsedError . message || 'Invalid request parameters' ,
81
- details : parsedError ,
124
+ message : sanitizeErrorMessage ( parsedError . message || 'Invalid request parameters' ) ,
125
+ details : sanitizeErrorDetails ( parsedError ) ,
82
126
suggestion : 'Please verify all required parameters are provided and have valid values.'
83
127
} ;
84
128
}
@@ -104,9 +148,9 @@ function getErrorDetails(response: Response, responseText: string): CoinbaseErro
104
148
// Default unknown error
105
149
return {
106
150
type : CoinbaseErrorType . UNKNOWN ,
107
- message : `Unexpected error: ${ response . statusText } ` ,
108
- details : parsedError ,
109
- suggestion : 'If this persists, please contact team with the error details.'
151
+ message : sanitizeErrorMessage ( `Unexpected error: ${ response . statusText } ` ) ,
152
+ details : sanitizeErrorDetails ( parsedError ) ,
153
+ suggestion : 'If this persists, please contact support with the error details.'
110
154
} ;
111
155
}
112
156
@@ -118,6 +162,11 @@ export function handleException(
118
162
if ( ( 400 <= response . status && response . status <= 499 ) ||
119
163
( 500 <= response . status && response . status <= 599 ) ) {
120
164
const errorDetails = getErrorDetails ( response , responseText ) ;
165
+ // Ensure all error information is sanitized
166
+ errorDetails . message = sanitizeErrorMessage ( errorDetails . message ) ;
167
+ if ( errorDetails . details ) {
168
+ errorDetails . details = sanitizeErrorDetails ( errorDetails . details ) ;
169
+ }
121
170
throw new CoinbaseError ( errorDetails , response . status , response ) ;
122
171
}
123
172
}
0 commit comments