JS learning notes -- basic introduction and use of try finally exception mechanism

Posted by lanbor on Sat, 01 Jan 2022 20:42:17 +0100

premise

Usually, we use the try {} catch {} mechanism to catch error exceptions in the code. Today, when looking at the project, we suddenly find that try {} finally {} is used to catch exceptions. This method has not been used much before, so we also checked the data and conducted in-depth research.

try finally

(1) Grammar

Another important part of the exception mechanism is finally.
catch can be followed by a finally statement. The syntax is as follows:

try{
    //Exceptions may be thrown
}catch(Exception e){
    //Catch exception
}finally{
    //Execute with or without exceptions
}

finally, the code will be executed whether there is an exception or not.

(2) Operating mechanism

  • If no exception occurs, the code in finally will be executed after the code in try is executed
  • If an exception occurs and is caught by catch, the code in finally will be executed after the code in catch is executed
  • If an exception occurs but is not caught, it is executed before the exception is thrown to the upper layer

It is worth noting that in the try/catch/finally syntax, catch is not required, that is, only try/finally can be used, which means that exceptions are not caught and are automatically passed upward, but the code in finally is also executed after the exception occurs.

(3)return

(1) return in try

In the try / catch / finally statement, there is a detail, that is, if there is a return in the try or catch, the return statement will not be executed until the execution of the finally statement is completed, but finally cannot change the return value immediately. We can see the following code:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            return setVal(1234)
        } catch (error) {
            console.log('error',error)
        }finally{
            setVal(9999)
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                Ha ha ha ha ha
            </h1>
            <h2>
                Current val Value:{val}
            </h2>
        </div>
    );
};

export default App;

design sketch:

It can be seen that:
The return value of this function is 9999, not 1234. The actual implementation process is:

  1. Before executing the return setVal (1234) statement in try, the return value val will be saved in a temporary variable
  2. Then execute the finally statement
  3. Finally, try returns the temporary variable, and the modification of val in finally will not be returned
(2) return in finally

If there is a return statement in finally, what will happen?
If finally also contains a return, the return in try and catch will be lost and the return value in finally will actually be returned.

In fact, return in finally will not only cover the return values in try and catch, but also cover up the exceptions in try and catch as if the exception did not occur, for example:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            let aaa = 111/0
            return setVal(aaa)
        } catch (error) {
            console.log('error',error)
        }finally{
            setVal(9999)
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                Ha ha ha ha ha
            </h1>
            <h2>
                Current val Value:{val}
            </h2>
        </div>
    );
};
export default App;

design sketch:

It can be found that:

  • The function in try has an error, but no exception is thrown.
  • The return in finally overwrites the error and no longer passes it up.

In fact, not only the return statement in finally will mask the exception, but if an exception is thrown in finally, the original exception will be masked. See the following code:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            let aaa = 111/0
            return setVal(aaa)
        } catch (error) {
            console.log('error',error)
        }finally{
            let bbb = 33/0
            // throw new Error('error ')
            return (
                setVal(bbb),
                console.log('finally error')
            )
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                Ha ha ha ha ha
            </h1>
            <h2>
                Current val Value:{val}
            </h2>
        </div>
    );
};
export default App;

design sketch:

It can be found that:

  • finally, an error was thrown

Therefore, in general, to avoid confusion, you should avoid using return statements or throwing exceptions in finally. If other code called may throw exceptions, you should catch and handle the exceptions.

Topics: Javascript