@@ -73,6 +73,7 @@ const {
73
73
codes : {
74
74
ERR_ACCESS_DENIED ,
75
75
ERR_FS_FILE_TOO_LARGE ,
76
+ ERR_INVALID_ARG_TYPE ,
76
77
ERR_INVALID_ARG_VALUE ,
77
78
} ,
78
79
} = require ( 'internal/errors' ) ;
@@ -1620,22 +1621,57 @@ function lstat(path, options = { bigint: false }, callback) {
1620
1621
/**
1621
1622
* Asynchronously gets the stats of a file.
1622
1623
* @param {string | Buffer | URL } path
1623
- * @param {{ bigint?: boolean; } } [options]
1624
+ * @param {{ bigint?: boolean, signal?: AbortSignal } } [options]
1624
1625
* @param {(
1625
1626
* err?: Error,
1626
1627
* stats?: Stats
1627
1628
* ) => any} callback
1628
1629
* @returns {void }
1629
1630
*/
1630
- function stat ( path , options = { bigint : false } , callback ) {
1631
+ function stat ( path , options = { __proto__ : null , bigint : false , signal : undefined } , callback ) {
1631
1632
if ( typeof options === 'function' ) {
1632
1633
callback = options ;
1633
1634
options = kEmptyObject ;
1635
+ } else if ( options === null || typeof options !== 'object' ) {
1636
+ options = kEmptyObject ;
1637
+ } else {
1638
+ options = getOptions ( options , { __proto__ : null , bigint : false , signal : undefined } ) ;
1639
+ }
1640
+
1641
+ if ( typeof callback !== 'function' ) {
1642
+ throw new ERR_INVALID_ARG_TYPE ( 'callback' , 'Function' , callback ) ;
1634
1643
}
1635
- callback = makeStatsCallback ( callback ) ;
1636
1644
1645
+ const originalCallback = callback ;
1637
1646
const req = new FSReqCallback ( options . bigint ) ;
1638
- req . oncomplete = callback ;
1647
+
1648
+ if ( options . signal ?. aborted ) {
1649
+ const abortErr = new AbortError ( 'The operation was aborted' , { __proto__ : null , cause : options . signal . reason } ) ;
1650
+ return process . nextTick ( ( ) => originalCallback ( abortErr ) ) ;
1651
+ }
1652
+
1653
+ let aborted = false ;
1654
+ const onAbort = ( ) => {
1655
+ aborted = true ;
1656
+ originalCallback ( new AbortError ( undefined , { __proto__ : null , cause : options . signal . reason } ) ) ;
1657
+ } ;
1658
+
1659
+ if ( options . signal ) {
1660
+ options . signal . addEventListener ( 'abort' , onAbort , { __proto__ : null , once : true } ) ;
1661
+ }
1662
+
1663
+ req . oncomplete = ( err , stats ) => {
1664
+ if ( options . signal ) {
1665
+ options . signal . removeEventListener ( 'abort' , onAbort ) ;
1666
+ }
1667
+
1668
+ if ( aborted ) return ;
1669
+
1670
+ const wrappedCallback = makeStatsCallback ( originalCallback ) ;
1671
+
1672
+ wrappedCallback ( err , stats ) ;
1673
+ } ;
1674
+
1639
1675
binding . stat ( getValidatedPath ( path ) , options . bigint , req ) ;
1640
1676
}
1641
1677
0 commit comments