regenerator icon indicating copy to clipboard operation
regenerator copied to clipboard

plugin-transform-regenerator can produce infinite loop using async/await and nested try/catch/finally

Open babel-bot opened this issue 5 years ago • 1 comments

Original issue submitted by @mgroenhoff in https://github.com/babel/babel/issues/9019

Bug Report

Current Behavior The state machine produced by @babel/plugin-transform-regenerator is incorrect and can produce an infinite loop using nested try/catch/finally statements inside a loop together with async/await as shown in the example below.

If I run the code from the repl below with node it loops two times and then exits the loop. If I run the code produced by babel it loops 10 times.

Input Code

let call = 0;
async function callback() {
    ++call;
    if (call < 2) {
        throw new Error("err");
    }
    call = 0;
}

async function main() {
    let retry;
    do {
      	retry = false;
        let result;
        try {
            try {
                result = await callback();
                console.log("success");
            } catch (error) {
                console.log("error 1");
                throw error;
            }/* finally {
                // If I enable this finally block and `await callback()` does not throw ("success"), it jumps to the outer catch block ("error 2") below
                console.log("finally 1");
            }*/
        } catch (error) {
            console.log("error 2");
            retry = true;
        } finally {
            console.log("finally 2");
        }
    } while (retry);
}

main();

See repl

Expected behavior/code If I uncomment the inner finally everything works as expected. See repl

babel-bot avatar Mar 26 '19 23:03 babel-bot

Either by way of luck or thoughtfulness, there is currently no clash between built-in PropTypes names and reserved words and I'd like to keep it that way.

This is what I currently do to make my propTypes more readable:

const {bool, func, number, shape, string} = PropTypes;

MyComponent.propTypes = {
  foo: number.isRequired,
  bar: shape({
    x: string,
    y: bool.isRequired
  })
};

As you can see, I rely on there being no naming clash. And I can't be the only person doing this.

So it's a -1 from me.

steve-taylor avatar Apr 10 '17 03:04 steve-taylor

@gaearon in this issue facebook/react#8951 you suggested an warning. Could you please let me know what do we want to warn so I can look at contributing

bytetwin avatar Apr 22 '17 15:04 bytetwin

Don't deprecate func, just add function as an alias.

function can be for those who prefer PropTypes.function and func will stay for those who prefer to destructure it first.

Similarly, there should be bool and boolean.

merlinstardust avatar Sep 01 '18 19:09 merlinstardust