Use return to return error data in a specific format
Let's explain it with an example, as shown in the following code:
// A method to verify data (using return to return data in a specific format)const validateData = (data) => { if (!) { return { pass: false, message: 'The name cannot be empty' } } } // A method to submit data, in which the verification method is calledconst submit = (data) => { const res = validateData(data); if (!) { // Prompt the user error message alert(); } } submit({ name: '' });
In the above code,validateData
Methods use return to return data in a specific format and are called before submitting the data.validateData
Method to verify the data, and the verification does not pass and prompt the user with an error message.
The above example is a situation that is often encountered in front-end projects, but in back-end projects, the focus is not to prompt the user for error information, but to return error information in a specific format in the interface, for example:
// A method to verify data (using return to return data in a specific format)const validateData = (data) => { if (!) { return { pass: false, message: 'The name cannot be empty' } } } // A method that adds a row of data to the database table, in which the verification method is called, the data returned by return will be used as the return data of the interfaceconst addRow = (data) => { const res = validateData(data); if (!) { return { code: -1, message: } } // Add new data to the database} addRow({ name: '' });
In the above code, pass two layersreturn
Return data; it is good to maintain such code when there are only two layers, but when the back-end code processing business is very complex and the method call level is very deep, it will become difficult to maintain, because each layer of method has to judge the return of the next layer and then process the structure and return it to the previous layer. Then I was thinking about how to make it easier? Think of using it directlythrow
to throw an error.
Use throw to throw an error
In the back-end project code, the main thing is to process the business logic and then return the results through the interface, unlike the front-end project code where there is some business logic and user interaction. So it is entirely possible to add a middleware to process all errors thrown in the code and then encapsulate them and return them to the interface caller. For example in the nodejs project:
// documentimport 'express-async-errors'; // After introducing this module, it can capture unprocessed asynchronous errors and pass them to the error handling middleware.import express from 'express'; import routes from './routes'; const app = express(); // Mount all routes at once(routes); // Global error handling middleware, all uncaught errors are processed here, and the business code can focus on business logic.((error, req, res, next) => { // Unified processing of all uncaught errors (200).json({ code: -1, message: error?.message || 'Server error! ', data: null }); }); // documentimport express from 'express'; const router = (); // A method to verify data (using thorw to throw errors)const validateData = (data) => { if (!) { throw new Error('The name cannot be empty'); } } // A method to add a row of data to the database table, in which the verification method is calledconst addRow = (data) => { // Verify data validateData(data); // Add new data to the database} // Define a route with the path /addRow and call the addRow method('/addRow', (req, res) => { addRow({ name: '' }); })
In this way, no matter how deep the method is usedthrow
Throw an error, as long as it is not caught, can be handled in the outermost layer.
Why do you need to "throw an error with throw and then handle it in the global error handling middleware"?
Because when the backend business logic is complex, there may be many levels of code calls, all of which use return to return data in a specific format is more complicated when writing and maintaining, and using throw to uniformly process it after throwing has these benefits:
-
Unified error handling, making code writing and maintenance easier
-
Unified error handling:pass
throw
Throwing errors and processing them in the global error handling middleware allows all types of errors (such as errors in routing processing, database operation errors, third-party API call errors, etc.) to be processed in one place; this can make the error handling logic clearer and more organized, avoiding the scattered distribution of error handling in various module methods. - Simple to write and maintain: In a deep-level method, you don’t need to consider the data return in the error situation, just throw the error directly; all error handling logic is in one place, and subsequent updates to error logic only need to modify this place for easy maintenance.
-
Unified error handling:pass
-
Enhance the stability of the program
- Prevent program crashes: If an error occurs in a method or module, if not processed, it may cause the entire program to crash; all uncaught errors can be handled through the global error handling middleware, which can prevent the program crash termination caused by a single error.
-
Consistent user experience
- Unified error message data structure: In the global error processing middleware, the data structure of the error message can be unified and returned to the client. This way the client code can better handle errors and display errors to the user.
- Clear error prompts: For some error codes, it can be converted into text prompts that the user can understand and returned to the client.
The above is the detailed content of the operation method of using throw for exception handling in nodejs. For more information about node throw exception handling, please pay attention to my other related articles!