* Print every diagnostic field a Postgres driver puts on a thrown error. The default * `error.message` loses the constraint name, affected table/column, PG code, and hint — * which are usually what you need to diagnose a failed migration.
(error: unknown)
| 253 | * which are usually what you need to diagnose a failed migration. |
| 254 | */ |
| 255 | function printMigrationError(error: unknown): void { |
| 256 | if (!(error instanceof Error)) { |
| 257 | console.error(error) |
| 258 | return |
| 259 | } |
| 260 | |
| 261 | console.error(`message: ${error.message}`) |
| 262 | |
| 263 | const pgFields = [ |
| 264 | 'code', |
| 265 | 'severity', |
| 266 | 'severity_local', |
| 267 | 'detail', |
| 268 | 'hint', |
| 269 | 'schema', |
| 270 | 'schema_name', |
| 271 | 'table', |
| 272 | 'table_name', |
| 273 | 'column', |
| 274 | 'column_name', |
| 275 | 'constraint', |
| 276 | 'constraint_name', |
| 277 | 'data_type', |
| 278 | 'where', |
| 279 | 'internal_query', |
| 280 | 'internal_position', |
| 281 | 'position', |
| 282 | 'routine', |
| 283 | 'file', |
| 284 | 'line', |
| 285 | ] as const |
| 286 | |
| 287 | const err = error as Record<string, unknown> |
| 288 | for (const field of pgFields) { |
| 289 | const value = err[field] |
| 290 | if (value !== undefined && value !== null && value !== '') { |
| 291 | console.error(`${field}: ${String(value)}`) |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | if (err.query && typeof err.query === 'string') { |
| 296 | console.error('\nfailing query:') |
| 297 | console.error(err.query) |
| 298 | } |
| 299 | |
| 300 | if (err.parameters !== undefined) { |
| 301 | console.error('\nparameters:') |
| 302 | console.error(err.parameters) |
| 303 | } |
| 304 | |
| 305 | if (error.cause) { |
| 306 | console.error('\ncause:') |
| 307 | printMigrationError(error.cause) |
| 308 | } |
| 309 | |
| 310 | if (error.stack) { |
| 311 | console.error('\nstack:') |
| 312 | console.error(error.stack) |