Commit Graph
83 Commits
Author SHA1 Message Date
Andrew ClarkandGitHub a39f7b3916 [suspense][error handling] Inline renderRoot and fix error handling bug (#16801)
* Outline push/pop logic in `renderRoot`

I want to get rid of the the `isSync` argument to `renderRoot`, and
instead use separate functions for concurrent and synchronous render.

As a first step, this extracts the push/pop logic that happens before
and after the render phase into helper functions.

* Extract `catch` block into helper function

Similar to previous commit. Extract error handling logic into
a separate function so it can be reused.

* Fork `renderRoot` for sync and concurrent

Removes `isSync` argument in favor of separate functions.

* Extra "root completion" logic to separate function

Moving this out to avoid an accidental early return, which would
bypass the call to `ensureRootIsScheduled` and freeze the UI.

* Inline `renderRoot`

Inlines `renderRoot` into `performConcurrentWorkOnRoot` and
`performSyncWorkOnRoot`. This lets me remove the `isSync` argument
and also get rid of a redundant try-catch wrapper.

* [suspense][error handling] Add failing unit test

Covers an edge case where an error is thrown inside the complete phase
of a component that is in the return path of a component that suspends.
The second error should also be handled (i.e. able to be captured by
an error boundary.

The test is currently failing because there's a call to
`completeUnitOfWork` inside the main render phase `catch` block. That
call is not itself wrapped in try-catch, so anything that throws is
treated as a fatal/unhandled error.

I believe this bug is only observable if something in the host config
throws; and, only in legacy mode, because in concurrent/batched mode,
`completeUnitOfWork` on fiber that throws follows the "unwind" path
only, not the "complete" path, and the "unwind" path does not call
any host config methods.

* [scheduler][profiler] Start time of delayed tasks

Fixes a bug in the Scheduler profiler where the start time of a delayed
tasks is always 0.

* Remove ad hoc `throw`

Fatal errors (errors that are not captured by an error boundary) are
currently rethrown from directly inside the render phase's `catch`
block. This is a refactor hazard because the code in this branch has
to mirror the code that happens at the end of the function, when exiting
the render phase in the normal case.

This commit moves the throw to the end, using a new root exit status.

* Handle errors that occur on unwind
2019-09-23 11:23:28 -07:00
Sebastian MarkbågeandGitHub f64586bc21 [Partial Hydration] Don't invoke listeners on parent of dehydrated event target (#16591)
* Don't invoke listeners on parent of dehydrated event target

* Move Suspense boundary check to getClosestInstanceFromNode

Now getClosestInstanceFromNode can return either a host component,
host text component or suspense component when the suspense
component is dehydrated.

We then use that to ignore events on a suspense component.

* Attach the HostRoot fiber to the DOM container

This lets us detect if an event happens on this root's subtree before it
has rendered something.

* Add todo

The approach of checking isFiberMounted answers if we might be in an
in-progress hydration but it doesn't answer which root or boundary
might be in-progress so we don't know what to wait for.

This needs some refactoring.

* Refactor isFiberMountedImpl to getNearestMountedFiber

We'll need the nearest boundary for event replaying so this prepares for
that.

This surfaced an issue that we attach Hydrating tag on the root but normally
this (and Placement) is attached on the child. This surfaced an issue
that this can lead to both Placement and Hydrating effects which is not
supported so we need to ensure that we only ever use one or the other.

* Add todo for bug I spotted

* Cache tags

* Check the ContainerInstanceKey before the InstanceKey

The container is inside the instance, so we must find it before the
instance, since otherwise we'll miss it.
2019-09-05 08:51:31 -07:00
Dominic GannawayandGitHub 6a3f5d63d1 [react-core] Add more support for experimental React Scope API (#16621) 2019-08-30 18:27:14 +01:00
LEE SUK JAEandSunil Pai 593e55e9b6 Fix link on error-codes/README.md (#16595) 2019-08-28 15:49:45 +01:00
Dan AbramovandGitHub a1609d13f6 Throw on unhandled SSR suspending (#16460)
* Throw on unhandled SSR suspending

* Add a nicer message when the flag is off

* Tweak internal refinement error message
2019-08-19 19:53:02 +01:00
Sebastian MarkbågeandGitHub e4d766f25a Refactor Partial Hydration (#16346)
* Move dehydrated to be child of regular SuspenseComponent

We now store the comment node on SuspenseState instead and that indicates
that this SuspenseComponent is still dehydrated.

We also store a child but that is only used to represent the DOM node for
deletions and getNextHostSibling.

* Move logic from DehydratedSuspenseComponent to SuspenseComponent

Forked based on SuspenseState.dehydrated instead.

* Retry logic for dehydrated boundary

We can now simplify the logic for retrying dehydrated boundaries without
hydrating. This is becomes simply a reconciliation against the dehydrated
fragment which gets deleted, and the new children gets inserted.

* Remove dehydrated from throw

Instead we use the regular Suspense path. To save code, we attach retry
listeners in the commit phase even though technically we don't have to.

* Pop to nearest Suspense

I think this is right...?

* Popping hydration state should skip past the dehydrated instance

* Split mount from update and special case suspended second pass

The DidCapture flag isn't used consistently in the same way. We need
further refactor for this.

* Reorganize update path

If we remove the dehydration status in the first pass and then do a second
pass because we suspended, then we need to continue as if it didn't
previously suspend. Since there is no fragment child etc.

However, we must readd the deletion.

* Schedule context work on the boundary and not the child

* Warn for Suspense hydration in legacy mode

It does a two pass render that client renders the content.

* Rename DehydratedSuspenseComponent -> DehydratedFragment

This now doesn't represent a suspense boundary itself. Its parent does.

This Fiber represents the fragment around the dehydrated content.

* Refactor returns

Avoids the temporary mutable variables. I kept losing track of them.

* Add a comment explaining the type.

Placing it in the type since that's the central point as opposed to spread
out.
2019-08-12 15:58:38 -07:00
Andrew ClarkandGitHub 7c10a994a5 Fix typo in error code map (#16373)
"responer" -> "responder"

I also removed an unused error code that never shipped.
2019-08-12 14:56:09 -07:00
7ecb1d9de6 Babel 7 (#16297)
Upgraded from Babel 6 to Babel 7.

The only significant change seems to be the way `@babel/plugin-transform-classes` handles classes differently from `babel-plugin-transform-es2015-classes`. In regular mode, the former injects a `_createClass` function that increases the bundle size, and in the latter it removes the safeguard checks. However, this is okay because we don't all classes in new features, and we want to deprecate class usage in the future in the react repo.

Co-authored-by: Luna Ruan <[email protected]>
Co-authored-by: Abdul Rauf <[email protected]>
Co-authored-by: Maksim Markelov <[email protected]>
2019-08-08 17:46:35 -07:00
Dominic GannawayandGitHub 520fc34334 [Flare] Tweaks to Flare system design and API (#16264) 2019-08-01 19:08:54 +01:00
Dominic GannawayandGitHub 44acf39c90 [Flare] Redesign core event system (#16163) 2019-07-23 23:46:44 +01:00
Dominic GannawayandGitHub 08ad2873c4 Adds experimental fundamental interface (#16049) 2019-07-19 22:20:28 +01:00
Dominic GannawayandAndrew Clark 498afc97c5 [Flare] Add useEvent hook implementation (#15927)
* [Flare] Add useEvent hook implementation

Validate hooks have decendent event components

Few fixes and displayName changes

Fix more responder bugs

Update error codes

* Add another test

* Address feedback
2019-06-20 19:12:40 -07:00
Moti ZilbermanandAndrew Clark da71ca70cb Construct Error at invariant call site for clearer stack traces (#15877) 2019-06-18 11:38:33 -07:00
Andrew ClarkandGitHub ec0a6d4d23 Don't extract errors in CI (#15758)
Removes `--extract-errors` argument from CI build script command.
Instead, the author is expected to run `yarn extract-errors` locally
or manually edit the error code map.

The lint rule should be sufficient to catch unminified errors, but
as an extra precaution, I added a post-build step that greps the
production bundles. The post-build step works even if someone disables
the lint rule for a specific line or file.
2019-05-29 14:20:29 -07:00
Andrew ClarkandGitHub 30d4109f8d Lint rule for unminified errors (#15757)
* Lint rule for unminified errors

Add a lint rule that fails if an invariant message is not part of the
error code map.

The goal is to be more disciplined about adding and modifiying
production error codes. Error codes should be consistent across releases
even if their wording changes, for continuity in logs.

Currently, error codes are added to the error code map via an automated
script that runs right before release. The problem with this approach is
that if someone modifies an error message in the source, but neglects to
modify the corresponding message in the error code map, then the message
will be assigned a new error code, instead of reusing the existing one.

Because the error extraction script only runs before a release, people
rarely modify the error code map in practice. By moving the extraction
step to the PR stage, it forces the author to consider whether the
message should be assigned a new error code. It also allows the reviewer
to review the changes.

The trade off is that it requires more effort and context to land new
error messages, or to modify existing ones, particular for new
contributors who are not familiar with our processes.

Since we already expect users to lint their code, I would argue the
additional burden is marginal. Even if they forget to run the lint
command locally, they will get quick feedback from the CI lint job,
which typically finishes within 2-3 minutes.

* Add unreleased error messages to map
2019-05-29 11:29:04 -07:00
Owen ContiandAndrew Clark f3145f8117 Fix double spaces. (#15641) 2019-05-28 10:34:18 -07:00
Andrew ClarkandGitHub 903f8688b4 Invariant that throws when committing wrong tree (#15517)
If React finishes rendering a tree, delays committing it (e.g.
Suspense), then subsequently starts over or renders a new tree, the
pending tree is no longer valid. That's because rendering a new work-in
progress mutates the old one in place.

The current structure of the work loop makes this hard to reason about
because, although `renderRoot` and `commitRoot` are separate functions,
they can't be interleaved. If they are interleaved by accident, it
either results in inconsistent render output or invariant violations
that are hard to debug.

This commit adds an invariant that throws if the new tree is the same as
the old one. This won't prevent all bugs of this class, but it should
catch the most common kind.

To implement the invariant, I store the finished tree on a field on the
root. We already had a field for this, but it was only being used for
the unstable `createBatch` feature.

A more rigorous way to address this type of problem could be to unify
`renderRoot` and `commitRoot` into a single function, so that it's
harder to accidentally interleave the two phases. I plan to do something
like this in a follow-up.
2019-05-13 16:15:50 -07:00
Andrew ClarkandGitHub d3304f2e37 Include full error messages in React Native build (#15363)
The React Native build does not minify error messages in production,
but it still needs to run the error messages transform to compile
`invariant` calls to `ReactError`. To do this, I added a `noMinify`
option to the Babel plugin. I also renamed it from
`minify-error-messages` to the more generic `transform-error-messages`.
2019-04-09 16:40:19 -07:00
Dan Abramov 60a61fe73f Release 16.8.5 2019-03-22 16:47:59 +00:00
Andrew ClarkandGitHub 130a0a7834 Compile invariant directly to throw expressions (#15071)
* Transform invariant to custom error type

This transforms calls to the invariant module:

```js
invariant(condition, 'A %s message that contains %s', adj, noun);
```

Into throw statements:

```js
if (!condition) {
  if (__DEV__) {
    throw ReactError(`A ${adj} message that contains ${noun}`);
  } else {
    throw ReactErrorProd(ERR_CODE, adj, noun);
  }
}
```

The only thing ReactError does is return an error whose name is set
to "Invariant Violation" to match the existing behavior.

ReactErrorProd is a special version used in production that throws
a minified error code, with a link to see to expanded form. This
replaces the reactProdInvariant module.

As a next step, I would like to replace our use of the invariant module
for user facing errors by transforming normal Error constructors to
ReactError and ReactErrorProd. (We can continue using invariant for
internal React errors that are meant to be unreachable, which was the
original purpose of invariant.)

* Use numbers instead of strings for error codes

* Use arguments instead of an array

I wasn't sure about this part so I asked Sebastian, and his rationale
was that using arguments will make ReactErrorProd slightly slower, but
using an array will likely make all the functions that throw slightly
slower to compile, so it's hard to say which way is better. But since
ReactErrorProd is in an error path, and fewer bytes is generally better,
no array is good.

* Casing nit
2019-03-18 13:58:03 -07:00
Andrew ClarkandGitHub e8036a1129 Swap expect(ReactNoop) for expect(Scheduler) (#14971)
* Swap expect(ReactNoop) for expect(Scheduler)

In the previous commits, I upgraded our custom Jest matchers for the
noop and test renderers to use Scheduler under the hood.

Now that all these matchers are using Scheduler, we can drop
support for passing ReactNoop and test roots and always pass
Scheduler directly.

* Externalize Scheduler in noop and test bundles

I also noticed we don't need to regenerator runtime in noop anymore.
2019-02-28 12:54:47 -08:00
Dan Abramov 0448d1f099 Release 16.8.2 2019-02-14 19:13:15 +00:00
Brian Vaughn da0e88304b 16.8.0 2019-02-06 08:04:00 +00:00
Andrew Clark 98bb25c411 React v16.7.0 2018-12-19 17:23:14 -08:00
Andrew ClarkandDan Abramov a567910164 Update error codes 2018-11-13 20:29:30 +00:00
Andrew Clark 98eef774df Update error codes for 16.6.1 release 2018-11-06 18:28:50 -08:00
Dan Abramov 78bc36ff80 Update error codes for 16.6.0 release 2018-10-23 16:29:35 -07:00
Abdul RaufandNathan Hunzaker 4772882104 Fix babel-preset-fbjs configure link in comment (#13666) 2018-10-21 12:23:24 -05:00
Dan Abramov f8fde93b90 Update error codes for 16.6.0-alpha.01fb17f release 2018-10-10 17:18:59 +01:00
Brian Vaughn edd1b64231 Update error codes for 16.5.2 release 2018-09-18 11:30:50 -07:00
Brian Vaughn b334069abd Revert "Update error codes for 16.6.0-alpha.0 release"
This reverts commit d51f875f28.
2018-09-18 11:00:04 -07:00
Brian Vaughn d51f875f28 Update error codes for 16.6.0-alpha.0 release 2018-09-17 15:05:46 -07:00
Dan Abramov 1d1b9fc7ec Update error codes for 16.5.1 release 2018-09-13 19:31:18 +01:00
Héctor RamosandGitHub 7353a5add1 Drop the year from Facebook copyright headers and the LICENSE file. (#13593) 2018-09-07 15:11:23 -07:00
Brian Vaughn 8977695daf Update error codes for 16.5.0 release 2018-09-06 09:34:27 -07:00
Dan AbramovandGitHub 8076333d56 Remove fbjs dependency (#13069)
* Inline fbjs/lib/invariant

* Inline fbjs/lib/warning

* Remove remaining usage of fbjs in packages/*.js

* Fix lint

* Remove fbjs from dependencies

* Protect against accidental fbjs imports

* Fix broken test mocks

* Allow transitive deps on fbjs/ for UMD bundles

* Remove fbjs from release script
2018-06-19 16:03:45 +01:00
Dan Abramov fb8e90f2e5 Update error codes for 16.4.1 release 2018-06-13 17:20:35 +01:00
Andrew Clark e97e059429 Update error codes for 16.4.0 release 2018-05-23 17:35:31 -07:00
Dan 3986c7e78d Record sizes 2018-05-13 21:12:25 +01:00
Dan Abramov be219d794f Update error codes for 16.3.2 release 2018-04-16 16:23:12 +01:00
Dan AbramovandGitHub 80f6b01309 facebook.github.io/react -> reactjs.org (#12545) 2018-04-04 21:20:41 +01:00
Brian Vaughn 3695803a6b Update error codes for 16.3.0-alpha.2 release 2018-03-14 13:26:40 -07:00
Dan AbramovandGitHub a81365c84e Disable for...of by default, rewrite cases where it matters (#12198)
* Add no-for-of lint rule

* Ignore legit use cases of for..of

* Rewrite for..of in source code
2018-02-09 16:11:22 +00:00
Brian Vaughn 2d578b8e56 Update error codes for 16.3.0-alpha.0 release 2018-02-02 13:01:33 -08:00
Jack HouandDan Abramov 04a2d64b0f use different eslint config for es6 and es5 (#11794)
* use different eslint config for es6 and es5

* remove confusing eslint/baseConfig.js & add more eslint setting for es5, es6

* more clear way to run eslint on es5 & es6 file

* seperate ESNext, ES6, ES6 path, and use different lint config

* rename eslint config file & update eslint rules

* Undo yarn.lock changes

* Rename a file

* Remove unnecessary exceptions

* Refactor a little bit

* Refactor and tweak the logic

* Minor issues
2017-12-11 15:52:46 +00:00
Gabriel KalaniandDan Abramov b5261dbe9b refactor: scripts/error-codes (#11697)
Convert scripts/error-codes to use ES6 syntax
2017-11-29 01:13:12 +00:00
Dan Abramov a2376cf101 Update error codes for 16.1.0-beta.1 release 2017-11-07 14:53:31 +00:00
Brian Vaughn 593a09bed1 Update error codes for 16.1.0-beta release 2017-11-02 15:34:31 -07:00
Dan AbramovandGitHub 38f1974d79 Convert the Source to ES Modules (#11389)
* Update transforms to handle ES modules

* Update Jest to handle ES modules

* Convert react package to ES modules

* Convert react-art package to ES Modules

* Convert react-call-return package to ES Modules

* Convert react-test-renderer package to ES Modules

* Convert react-cs-renderer package to ES Modules

* Convert react-rt-renderer package to ES Modules

* Convert react-noop-renderer package to ES Modules

* Convert react-dom/server to ES modules

* Convert react-dom/{client,events,test-utils} to ES modules

* Convert react-dom/shared to ES modules

* Convert react-native-renderer to ES modules

* Convert react-reconciler to ES modules

* Convert events to ES modules

* Convert shared to ES modules

* Remove CommonJS support from transforms

* Move ReactDOMFB entry point code into react-dom/src

This is clearer because we can use ES imports in it.

* Fix Rollup shim configuration to work with ESM

* Fix incorrect comment

* Exclude external imports without side effects

* Fix ReactDOM FB build

* Remove TODOs I don’t intend to fix yet
2017-11-02 19:50:03 +00:00
Brian VaughnandGitHub 49d3841951 Added unit test that would have caught the recent error code transform regression (#11356)
* Added an automated test that would have caught the recent error code transform bug

* Renamed dev-expression-with-codes test to replace-invariant-error-codes

* Formatting nit
2017-10-25 08:21:55 -07:00