[ITEM 4] QUESTION: How to handle errors in async/await?
Proper error handling in async/await is the key to creating fault-tolerant JavaScript applications. Since traditional .catch methods are not always directly applicable to every line here, the standard approach is to use the classic try/catch construct. You wrap potentially dangerous asynchronous code in a try { await ... } block and, if any issue occurs, catch the error object in the catch (e) { } block, which allows you to flexibly respond to failures, display messages to the user, or log incidents.
An alternative option for targeted handling is to add the standard .catch() method directly to the call of the asynchronous function returning a promise, if you prefer a functional style. To implement mandatory cleanup actions, such as freeing memory or closing connections, the finally block is used, which executes at the very end regardless of whether the try block succeeded or caught an exception. You can successfully combine these approaches to create multi-layered protection for critical sections of your code.
If a developer forgets to wrap an asynchronous function call in a try/catch block or does not handle the promise it returns, unhandled errors occur in the system, leading to the unhandledrejection event. To prevent the application from crashing unexpectedly in a production environment, it is recommended to configure the interception of this event globally at the application level, which will allow centralized collection of failure statistics and graceful termination of critical background processes.