@@ -15,7 +15,6 @@ import { EventEmitter } from 'node:events';
1515import { Defaults } from './defaults.js' ;
1616import * as logger from './logging.js' ;
1717
18- import { postgresqlErrorCodes } from './errors.js' ;
1918import { Queue } from './queue.js' ;
2019import { Query } from './query.js' ;
2120
@@ -30,7 +29,6 @@ import {
3029 ClientConnectionDefaults ,
3130 ClientConnectionOptions ,
3231 DatabaseError ,
33- ErrorLevel ,
3432 Message ,
3533 Reader ,
3634 RowDescription ,
@@ -52,11 +50,7 @@ export interface ConnectionInfo {
5250 parameters : ReadonlyMap < string , string > ;
5351}
5452
55- export interface ClientNotice extends DatabaseError {
56- level : ErrorLevel ;
57- code : keyof typeof postgresqlErrorCodes ;
58- message : string ;
59- }
53+ export interface ClientNotice extends DatabaseError { }
6054
6155export interface DataTypeError {
6256 dataType : DataType ;
@@ -780,11 +774,7 @@ export class ClientImpl {
780774 }
781775
782776 private parseError ( buffer : Buffer ) {
783- let level : DatabaseError [ 'level' ] | null = null ;
784- let code : DatabaseError [ 'code' ] | null = null ;
785- let message : DatabaseError [ 'message' ] | null = null ;
786- let details : string | null = null ;
787-
777+ const params : Partial < ConstructorParameters < typeof DatabaseError > > = [ ] ;
788778 const length = buffer . length ;
789779 let offset = 0 ;
790780
@@ -793,45 +783,74 @@ export class ClientImpl {
793783 if ( next < 0 ) break ;
794784
795785 const value = buffer . subarray ( offset + 1 , next ) . toString ( ) ;
796- switch ( buffer [ offset ] ) {
786+
787+ // See https://www.postgresql.org/docs/current/protocol-error-fields.html
788+ const token = buffer [ offset ] ;
789+ switch ( token ) {
790+ // S:
797791 case 0x53 : {
798- if ( level === null ) {
799- level = value as DatabaseError [ 'level' ] ;
800- }
792+ params [ 0 ] = value as DatabaseError [ 'level' ] ;
801793 break ;
802794 }
795+ // V:
796+ // This is present only in messages generated by PostgreSQL
797+ // versions 9.6 and later, taking priority over the previous
798+ // case.
803799 case 0x56 : {
804- level = value as DatabaseError [ 'level' ] ;
800+ params [ 0 ] = value as DatabaseError [ 'level' ] ;
805801 break ;
806802 }
803+ // C:
807804 case 0x43 : {
808- code = value as DatabaseError [ 'code' ] ;
805+ params [ 1 ] = value as DatabaseError [ 'code' ] ;
809806 break ;
810807 }
808+ // M:
809+ case 0x4d : {
810+ params [ 2 ] = value ;
811+ break ;
812+ }
813+ // D:
811814 case 0x44 : {
812- details = value ;
815+ params [ 3 ] = value ;
813816 break ;
814817 }
815- case 0x4d : {
816- message = value ;
818+ // F:
819+ case 0x46 : {
820+ params [ 4 ] = value ;
817821 break ;
818822 }
819- default :
823+ // H:
824+ case 0x48 : {
825+ params [ 5 ] = value ;
820826 break ;
827+ }
828+ // L:
829+ case 0x4c : {
830+ params [ 6 ] = parseInt ( value ) ;
831+ break ;
832+ }
833+ // R:
834+ case 0x52 : {
835+ params [ 7 ] = value ;
836+ break ;
837+ }
838+ // P:
839+ case 0x50 : {
840+ params [ 8 ] = parseInt ( value ) ;
841+ break ;
842+ }
821843 }
822844
823845 offset = next + 1 ;
824846 }
825847
848+ const [ level , code , message , ...optional ] = params ;
826849 if ( level && code && message ) {
827- return new DatabaseError (
828- level ,
829- code ,
830- details ? `${ message } : ${ details } ` : message ,
831- ) ;
850+ return new DatabaseError ( level , code , message , ...optional ) ;
832851 }
833852
834- throw new Error ( 'Unable to parse error message. ' ) ;
853+ throw new Error ( 'Malformed error response ' ) ;
835854 }
836855
837856 private handle ( buffer : Buffer , offset : number , size : number ) : number {
@@ -1091,7 +1110,8 @@ export class ClientImpl {
10911110 buffer . subarray ( start , start + length ) ,
10921111 ) ;
10931112
1094- if ( this . connecting ) throw error ;
1113+ if ( this . connecting )
1114+ throw new Error ( `${ error . message } : ${ error . detail } ` ) ;
10951115
10961116 try {
10971117 this . events . emit ( 'error' , error ) ;
0 commit comments