11
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
- import { Request , Response , NextFunction , Express } from 'express' ;
14
+ import { Express } from 'express' ;
15
15
import { HandlerFunction } from '../functions' ;
16
16
import { ILayer } from 'express-serve-static-core' ;
17
17
@@ -31,72 +31,74 @@ const COMMON_EXPRESS_OBJECT_PROPERTIES = [
31
31
/** The number of parameters on an express error handler. */
32
32
const EXPRESS_ERROR_HANDLE_PARAM_LENGTH = 4 ;
33
33
34
- /** A express app error handle. */
35
- interface ErrorHandle {
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
- ( err : Error , req : Request , res : Response , next : NextFunction ) : any ;
38
- }
39
-
40
34
/**
41
- * Express middleware to propagate framework errors to the user function error handle.
42
- * This enables users to handle framework errors that would otherwise be handled by the
43
- * default Express error handle. If the user function doesn't have an error handle,
44
- * it falls back to the default Express error handle.
35
+ * Injects the user function error handle middleware and its subsequent middleware
36
+ * chain into the framework. This enables users to handle framework errors that would
37
+ * otherwise be handled by the default Express error handle.
38
+ * @param frameworkApp - Framework app
45
39
* @param userFunction - User handler function
46
40
*/
47
- export const createPropagateErrorToClientErrorHandleMiddleware = (
41
+ export const injectUserFunctionErrorHandleMiddlewareChain = (
42
+ frameworkApp : Express ,
48
43
userFunction : HandlerFunction
49
- ) : ErrorHandle => {
50
- const userFunctionErrorHandle =
51
- getFirstUserFunctionErrorHandleMiddleware ( userFunction ) ;
44
+ ) => {
45
+ // Check if user function is an express app that can register middleware.
46
+ if ( ! isExpressApp ( userFunction ) ) {
47
+ return ;
48
+ }
49
+
50
+ // Get the index of the user's first error handle middleware.
51
+ const firstErrorHandleMiddlewareIndex =
52
+ getFirstUserFunctionErrorHandleMiddlewareIndex ( userFunction ) ;
53
+ if ( ! firstErrorHandleMiddlewareIndex ) {
54
+ return ;
55
+ }
52
56
53
- return function (
54
- err : Error ,
55
- req : Request ,
56
- res : Response ,
57
- next : NextFunction
57
+ // Inject their error handle middleware chain into the framework app.
58
+ const middlewares = ( userFunction as Express ) . _router . stack ;
59
+ for (
60
+ let index = firstErrorHandleMiddlewareIndex ;
61
+ index < middlewares . length ;
62
+ index ++
58
63
) {
59
- // Propagate error to user function error handle.
60
- if ( userFunctionErrorHandle ) {
61
- return userFunctionErrorHandle ( err , req , res , next ) ;
64
+ const middleware = middlewares [ index ] ;
65
+
66
+ // We don't care about routes.
67
+ if ( middleware . route ) {
68
+ continue ;
62
69
}
63
70
64
- // Propagate error to default Express error handle.
65
- return next ( ) ;
66
- } ;
71
+ frameworkApp . use ( middleware . handle ) ;
72
+ }
67
73
} ;
68
74
69
75
/**
70
- * Returns the first user handler function defined error handle, if available .
71
- * @param userFunction - User handler function
76
+ * Returns if the user function contains common properties of an Express app .
77
+ * @param userFunction
72
78
*/
73
- const getFirstUserFunctionErrorHandleMiddleware = (
74
- userFunction : HandlerFunction
75
- ) : ErrorHandle | null => {
76
- if ( ! isExpressApp ( userFunction ) ) {
77
- return null ;
78
- }
79
+ const isExpressApp = ( userFunction : HandlerFunction ) : boolean => {
80
+ const userFunctionProperties = Object . getOwnPropertyNames ( userFunction ) ;
81
+ return COMMON_EXPRESS_OBJECT_PROPERTIES . every ( prop =>
82
+ userFunctionProperties . includes ( prop )
83
+ ) ;
84
+ } ;
79
85
86
+ /**
87
+ * Returns the index of the first error handle middleware in the user function.
88
+ */
89
+ const getFirstUserFunctionErrorHandleMiddlewareIndex = (
90
+ userFunction : HandlerFunction
91
+ ) : number | null => {
80
92
const middlewares : ILayer [ ] = ( userFunction as Express ) . _router . stack ;
81
- for ( const middleware of middlewares ) {
93
+ for ( let index = 0 ; index < middlewares . length ; index ++ ) {
94
+ const middleware = middlewares [ index ] ;
82
95
if (
83
96
middleware . handle &&
84
97
middleware . handle . length === EXPRESS_ERROR_HANDLE_PARAM_LENGTH
85
98
) {
86
- return middleware . handle as unknown as ErrorHandle ;
99
+ return index ;
87
100
}
88
101
}
89
102
90
103
return null ;
91
104
} ;
92
-
93
- /**
94
- * Returns if the user function contains common properties of an Express app.
95
- * @param userFunction
96
- */
97
- const isExpressApp = ( userFunction : HandlerFunction ) : boolean => {
98
- const userFunctionProperties = Object . getOwnPropertyNames ( userFunction ) ;
99
- return COMMON_EXPRESS_OBJECT_PROPERTIES . every ( prop =>
100
- userFunctionProperties . includes ( prop )
101
- ) ;
102
- } ;
0 commit comments