@@ -1506,6 +1506,13 @@ class Http2Stream extends Duplex {
1506
1506
this . once ( 'ready' , this . _destroy . bind ( this , err , callback ) ) ;
1507
1507
return ;
1508
1508
}
1509
+
1510
+ const server = session [ kServer ] ;
1511
+
1512
+ if ( err && server ) {
1513
+ server . emit ( 'streamError' , err , this ) ;
1514
+ }
1515
+
1509
1516
process . nextTick ( ( ) => {
1510
1517
debug ( `[${ sessionName ( session [ kType ] ) } ] destroying stream ${ this [ kID ] } ` ) ;
1511
1518
@@ -1529,9 +1536,8 @@ class Http2Stream extends Duplex {
1529
1536
// All done
1530
1537
const rst = this [ kState ] . rst ;
1531
1538
const code = rst ? this [ kState ] . rstCode : NGHTTP2_NO_ERROR ;
1532
- if ( code !== NGHTTP2_NO_ERROR ) {
1533
- const err = new errors . Error ( 'ERR_HTTP2_STREAM_ERROR' , code ) ;
1534
- process . nextTick ( ( ) => this . emit ( 'error' , err ) ) ;
1539
+ if ( ! err && code !== NGHTTP2_NO_ERROR ) {
1540
+ err = new errors . Error ( 'ERR_HTTP2_STREAM_ERROR' , code ) ;
1535
1541
}
1536
1542
process . nextTick ( emit . bind ( this , 'streamClosed' , code ) ) ;
1537
1543
debug ( `[${ sessionName ( session [ kType ] ) } ] stream ${ this [ kID ] } destroyed` ) ;
@@ -1634,13 +1640,24 @@ function doSendFileFD(session, options, fd, headers, getTrailers, err, stat) {
1634
1640
abort ( this ) ;
1635
1641
return ;
1636
1642
}
1643
+ const onError = options . onError ;
1644
+
1637
1645
if ( err ) {
1638
- process . nextTick ( ( ) => this . emit ( 'error' , err ) ) ;
1646
+ if ( onError ) {
1647
+ onError ( err ) ;
1648
+ } else {
1649
+ this . destroy ( err ) ;
1650
+ }
1639
1651
return ;
1640
1652
}
1653
+
1641
1654
if ( ! stat . isFile ( ) ) {
1642
1655
err = new errors . Error ( 'ERR_HTTP2_SEND_FILE' ) ;
1643
- process . nextTick ( ( ) => this . emit ( 'error' , err ) ) ;
1656
+ if ( onError ) {
1657
+ onError ( err ) ;
1658
+ } else {
1659
+ this . destroy ( err ) ;
1660
+ }
1644
1661
return ;
1645
1662
}
1646
1663
@@ -1677,12 +1694,17 @@ function doSendFileFD(session, options, fd, headers, getTrailers, err, stat) {
1677
1694
1678
1695
function afterOpen ( session , options , headers , getTrailers , err , fd ) {
1679
1696
const state = this [ kState ] ;
1697
+ const onError = options . onError ;
1680
1698
if ( this . destroyed || session . destroyed ) {
1681
1699
abort ( this ) ;
1682
1700
return ;
1683
1701
}
1684
1702
if ( err ) {
1685
- process . nextTick ( ( ) => this . emit ( 'error' , err ) ) ;
1703
+ if ( onError ) {
1704
+ onError ( err ) ;
1705
+ } else {
1706
+ this . destroy ( err ) ;
1707
+ }
1686
1708
return ;
1687
1709
}
1688
1710
state . fd = fd ;
@@ -1691,13 +1713,20 @@ function afterOpen(session, options, headers, getTrailers, err, fd) {
1691
1713
doSendFileFD . bind ( this , session , options , fd , headers , getTrailers ) ) ;
1692
1714
}
1693
1715
1716
+ function streamOnError ( err ) {
1717
+ // we swallow the error for parity with HTTP1
1718
+ // all the errors that ends here are not critical for the project
1719
+ debug ( 'ServerHttp2Stream errored, avoiding uncaughtException' , err ) ;
1720
+ }
1721
+
1694
1722
1695
1723
class ServerHttp2Stream extends Http2Stream {
1696
1724
constructor ( session , id , options , headers ) {
1697
1725
super ( session , options ) ;
1698
1726
this [ kInit ] ( id ) ;
1699
1727
this [ kProtocol ] = headers [ HTTP2_HEADER_SCHEME ] ;
1700
1728
this [ kAuthority ] = headers [ HTTP2_HEADER_AUTHORITY ] ;
1729
+ this . on ( 'error' , streamOnError ) ;
1701
1730
debug ( `[${ sessionName ( session [ kType ] ) } ] created serverhttp2stream` ) ;
1702
1731
}
1703
1732
@@ -2556,6 +2585,8 @@ module.exports = {
2556
2585
createServer,
2557
2586
createSecureServer,
2558
2587
connect,
2588
+ Http2Session,
2589
+ Http2Stream,
2559
2590
Http2ServerRequest,
2560
2591
Http2ServerResponse
2561
2592
} ;
0 commit comments