The official recommendation in the EggJS project is to use middleware for capture, and the KOA2 middleware principle was introduced in the previous article.
try… catch
I just noticed that the implementation was essentially recursive. But the try… What the catch layer of code does.
When middleware is a synchronization function:
Running fn directly will result in a try.. Catch to terminate subsequent middleware execution.
If fn executes successfully, use promise.resolve to ensure that a Promise instance is returned.
When middleware is an async function:
The middleware returns the Promise instance and passes it as a parameter to the promise.resolve function.
Resolve has the feature that when the argument is a Prmoise instance, the resovle function will not be executed until the instance is resolved, i.e., waiting for async to complete.
This is the core of KOA middleware: multiple asynchronous middleware calls, with the current middleware function writing “await next()”, will cause the current middleware to wait until the next middleware asynchronously executes its own logic.
The implementation of async and error capture
The run function below is how async is implemented. Use try… in run functions. Catch is used to catch errors.
Consider that if you don’t use a try in a generator function… Catch catches errors, so use try… Catch catches yield run-time errors and task.throw(ERR) errors and extracts the end generator function run.
However, if you use try… If the catch catches the yield error, then the try inside the run function… A catch is not triggered.
Insert two layers of try… catch
How does a generator function catch a Promise instance whose state is onRejected?
When the generator function yield/await returns an instance of a Promise in the onRejected state, result.value in the run function is a promise.
Resulte. Value, the Promise instance in the onRejected state, is passed to Promise.resolve, which calls the catch callback.
The catch callback calls task.throw, and the next time step is called, if there is no try inside the generator function… Catch catch task.throw, then use the try inside step… Catch, and prematurely terminates generator function execution.
The instance
Here are a few examples
Middleware handles errors uniformly
Multiple middleware error catching:
Middleware 1: Error catching
Middleware 2: authentication
Middleware 3: Other middleware that throws errors
Output:
auth before
test before
catch error
The phenomenon of analysis
The theoretical order of middleware is: error -> Auth -> test. Because of the function call stack, an onion ring model is formed. However, the situation now is that the test execution reported an error, so the behavior is a little different.
The output results of strength show that:
1. Errors in the later middleware can be caught in the first middleware
2. The code after each middleware function await next() is not executed, i.e., only half of the onion ring is left.
The principle of analysis
1. An error is thrown in the test middleware. It can be seen from the implementation principle of Async that the middleware returns a Promise instance of the onRejected state, and the test function code is not completed, that is, the next iteration will not be performed, so all middleware after the call of test will be terminated.
Resolve (fn(context, diapatch.bind(null, I +1)))
Auth middleware await next() until test is finished and test returns a Promise in the onRejected state, so auth will await next() as well. And returns a new Promise with the onRejected state
The error middleware await next() will also wait until auth finishes, and likewise the Auth terminates early and returns another new onRejected Promise.
Finally, try… Catch catches the onRejected state promise and does a deal with the error.
conclusion
According to the implementation principle of async, async needs to catch both synchronous and asynchronous errors
1. Inside async functions we can use try… Catch catches an instance of a Promise in the onRejected state, which can catch yield errors (if there is no other catch in the generator function)
2. Do not use try inside async functions… Catch catches an error, and the async function terminates prematurely and returns a Promise with an onRejected state
According to the principle of KOA middleware,
Inside middleware functions await next() is essentially a recursive call to dispatch(I +1).
1. If the next middleware does not use a try internally… Catch catches an error, and the middleware function returns an onRejected state Promise instance, Dispatch. Abort middleware execution early.
2. If the middleware uses a try… Catch catches an error, and the function is fully executed.
The last
The last article about middleware,, I think I really understand…..