mirror of
https://github.com/facebook/react.git
synced 2026-02-21 19:31:52 +00:00
[compiler] Fix invariant error for optional chaining in try/catch
Optional chaining and other value blocks within try/catch blocks were throwing an Invariant error ("Unexpected terminal in optional") instead of the expected Todo error. This caused hard failures instead of graceful bailouts.
The issue occurred because DropManualMemoization and ValidateExhaustiveDependencies ran before BuildReactiveFunction, and encountered `maybe-throw` terminals in their switch statements without a handler, falling through to the invariant case.
Fixed by adding explicit `maybe-throw` cases in both files that throw the proper Todo error with the message "Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement".
Also renamed the existing bug test to reflect it's now correctly handled:
- error.bug-invariant-unexpected-terminal-in-optional → error.todo-optional-chaining-within-try-catch
Closes #35570
This commit is contained in:
@@ -583,6 +583,14 @@ function findOptionalPlaces(fn: HIRFunction): Set<IdentifierId> {
|
||||
testBlock = fn.body.blocks.get(terminal.fallthrough)!;
|
||||
break;
|
||||
}
|
||||
case 'maybe-throw': {
|
||||
CompilerError.throwTodo({
|
||||
reason: `Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement`,
|
||||
description: null,
|
||||
loc: terminal.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
default: {
|
||||
CompilerError.invariant(false, {
|
||||
reason: `Unexpected terminal in optional`,
|
||||
|
||||
@@ -1016,6 +1016,14 @@ export function findOptionalPlaces(
|
||||
testBlock = fn.body.blocks.get(terminal.block)!;
|
||||
break;
|
||||
}
|
||||
case 'maybe-throw': {
|
||||
CompilerError.throwTodo({
|
||||
reason: `Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement`,
|
||||
description: null,
|
||||
loc: terminal.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
default: {
|
||||
CompilerError.simpleInvariant(false, {
|
||||
reason: `Unexpected terminal in optional`,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const callback = async () => {
|
||||
try {
|
||||
const result = await fetch(props.url);
|
||||
return result?.error;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return callback;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
|
||||
Todo: Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement
|
||||
|
||||
error.todo-optional-chaining-within-try-catch-in-callback.ts:5:13
|
||||
3 | try {
|
||||
4 | const result = await fetch(props.url);
|
||||
> 5 | return result?.error;
|
||||
| ^^^^^^ Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement
|
||||
6 | } catch (e) {
|
||||
7 | return null;
|
||||
8 | }
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
function Component(props) {
|
||||
const callback = async () => {
|
||||
try {
|
||||
const result = await fetch(props.url);
|
||||
return result?.error;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return callback;
|
||||
}
|
||||
@@ -19,13 +19,13 @@ const Foo = ({json}) => {
|
||||
```
|
||||
Found 1 error:
|
||||
|
||||
Invariant: Unexpected terminal in optional
|
||||
Todo: Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement
|
||||
|
||||
error.bug-invariant-unexpected-terminal-in-optional.ts:3:16
|
||||
error.todo-optional-chaining-within-try-catch.ts:3:16
|
||||
1 | const Foo = ({json}) => {
|
||||
2 | try {
|
||||
> 3 | const foo = JSON.parse(json)?.foo;
|
||||
| ^^^^ Unexpected maybe-throw in optional
|
||||
| ^^^^ Support value blocks (conditional, logical, optional chaining, etc) within a try/catch statement
|
||||
4 | return <span>{foo}</span>;
|
||||
5 | } catch {
|
||||
6 | return null;
|
||||
Reference in New Issue
Block a user