Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot read property 'configuration of undefined' when calling stop on an interpreter that was not initialized #1697

Closed
AlCalzone opened this issue Dec 6, 2020 · 6 comments · Fixed by #1710

Comments

@AlCalzone
Copy link

AlCalzone commented Dec 6, 2020

Description
Recently, my tests are failing due to a crash in xstate. It seems that this happens because the interpreter was not initialized (see repro below).

Summary of all failing tests
 FAIL  packages/zwave-js/src/lib/driver/Driver.test.ts (6.342 s)
  ● lib/driver/Driver =>  › sending messages =>  › should not be possible if the driver failed to start

    TypeError: Cannot read property 'configuration' of undefined

      1222 | 
      1223 |            // First stop the send thread machine and close the serial port, so nothing happens anymore
    > 1224 |            this.sendThread.stop();
           |                            ^
      1225 |            if (this.serial != undefined) {
      1226 |                    if (this.serial.isOpen) await this.serial.close();
      1227 |                    this.serial = undefined;

      at Interpreter.stop (node_modules/xstate/lib/interpreter.js:487:20)
      at Driver.destroy (packages/zwave-js/src/lib/driver/Driver.ts:1224:19)
      at Object.<anonymous> (packages/zwave-js/src/lib/driver/Driver.test.ts:140:11)

Expected Result
No crash

Actual Result
crash

Reproduction

  1. clone https://github.com/zwave-js/node-zwave-js/commit/18a000888b12143409569241e0128aac9f476499
  2. run npm run test:ts -- --testPathPattern=driver/Driver.test.ts
$ npm run test:ts -- --testPathPattern=driver/Driver.test.ts

> test:ts
> jest "--testPathPattern=driver/Driver.test.ts"

  console.warn
    Warning: Attempted to read state from uninitialized service 'SendThread'. Make sure the service is started first.

      1222 | 
      1223 |            // First stop the send thread machine and close the serial port, so nothing happens anymore
    > 1224 |            this.sendThread.stop();
           |                            ^
      1225 |            if (this.serial != undefined) {
      1226 |                    if (this.serial.isOpen) await this.serial.close();
      1227 |                    this.serial = undefined;

[...]

  ● lib/driver/Driver =>  › sending messages =>  › should not be possible if the driver failed to start

    TypeError: Cannot read property 'configuration' of undefined

      1222 | 
      1223 |            // First stop the send thread machine and close the serial port, so nothing happens anymore
    > 1224 |            this.sendThread.stop();
           |                            ^
      1225 |            if (this.serial != undefined) {
      1226 |                    if (this.serial.isOpen) await this.serial.close();
      1227 |                    this.serial = undefined;

      at Interpreter.stop (node_modules/xstate/lib/interpreter.js:487:20)
      at Driver.destroy (packages/zwave-js/src/lib/driver/Driver.ts:1224:19)
      at Object.<anonymous> (packages/zwave-js/src/lib/driver/Driver.test.ts:140:11)

Test Suites: 1 failed, 1 total

Additional context

@AlCalzone AlCalzone changed the title TypeError: Cannot read property TypeError: Cannot read property 'configuration of undefined' when stopping interpreter Dec 6, 2020
@AlCalzone AlCalzone reopened this Dec 6, 2020
@AlCalzone AlCalzone changed the title TypeError: Cannot read property 'configuration of undefined' when stopping interpreter TypeError: Cannot read property 'configuration of undefined' when calling stop on an interpreter that was not initialized Dec 6, 2020
@davidkpiano
Copy link
Member

You can mitigate this:

if (this.sendThread.initialized) {
  this.sendThread.stop();
}

Or put it in a try/catch. If you can create a simple reproducible example in CodeSandbox, that would be easier for us to work with than cloning/running a repo.

@Andarist
Copy link
Member

Andarist commented Dec 8, 2020

So this is a funny issue... It manifests itself only if those 2 tests are "enabled" (you can just remove the rest of the file to test this out):

This made me suspect a shared state between those 2 because that second test fails only if the first one is executed as well.. I couldn't really find any shared state so I've added an __id property to your Driver class, caught the error, appended that this.__id to its message, and I've rethrown the error. This told me that the error that fails the test is actually the error thrown by the first of the listed tests. So why the second test fails? I believe that Jest just implements a logic similar to Cypress (and probably other testing frameworks) which is failing tests on any uncaught errors - this is good logic, often surfacing problems that were not explicitly tested against. And because your destroy method is actually an async method, the error thrown within it gets caught by Jest when it already executes other test - after all, there is no easy way to track "ownership" of an async job in JS.

If we add await to this destroy call:
https://github.com/zwave-js/node-zwave-js/blob/18a000888b12143409569241e0128aac9f476499/packages/zwave-js/src/lib/driver/Driver.test.ts#L140
we'll end up with the correct test being failed by Jest. I believe you should add this (and similar) awaits universally across the whole project in your tests - it would help you to reason about your tests better in the future.

As to the original issue - the solution proposed by @davidkpiano seems like the most appropriate one. This test that has caused all of this problem is never calling start and thus it's never calling this.sendThread.start():
https://github.com/zwave-js/node-zwave-js/blob/18a000888b12143409569241e0128aac9f476499/packages/zwave-js/src/lib/driver/Driver.test.ts#L130-L141
So its destroy doesn't really have anything to stop.

@AlCalzone
Copy link
Author

@Andarist Oh wow, thanks for the detailed investigation. I can confirm that @davidkpiano's solution does work and I'll add awaits for the destroy calls. So I can definitely work around the issue.

However this behavior seems to have changed with an xstate update and I think that calling stop before start should not cause a crash.

@Andarist
Copy link
Member

Andarist commented Dec 9, 2020

However this behavior seems to have changed with an xstate update and I think that calling stop before start should not cause a crash.

I don't have super strong opinion about this one. It makes sense for me both ways so kinda 🤷‍♂️ Any preference @davidkpiano ?

@AlCalzone
Copy link
Author

To add:

calling stop before start should not cause a crash.

If it crashes (which might be desired), it should be with a clear error message like cannot stop an interpreter that was not started or something along these lines.

@davidkpiano
Copy link
Member

davidkpiano commented Dec 9, 2020

We can show a warning. I'll do that. EDIT: It should suffice to just not do anything (except clean up listeners) when stopping an already stopped service.

dsngo added a commit to dsngo/xstate that referenced this issue Feb 24, 2021
* Created xstate-svelte directory and added support for @xstate/fsm.

* Added support for xstate and tests.

* Updated svelte-jester to allow running tests from project root.

* Add createModel + test

* Update test to show full typing

* Rename withUpdaters -> withAssigners, fix mapValue types

* Fix typings for createModel

* Improve types

* Do not crash when stopping already stopped interpreter. Fixes statelyai#1697

* Add changeset

* WIP: model updates

* Simplify model

* Add comment

* Update resources.md

* Fixed an issue with `process` references not being removed correctly from the `@xstate/react` UMD bundles (statelyai#1756)

* 'rollup-replace' replaces process.env.NODE_ENV declarations.

* rollup-replace is a dependency.

* 'rollup-replace' replaces process.env.NODE_ENV declarations.

* Use the same version of rollup-plugin-replace across the repo

* tweak changeset

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Version Packages (statelyai#1760)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Rename context -> initialContext, use ExtractEvent

* Remove actions property

* Fix types

* Update description in svelte.md

Add import statement: import replace from "@rollup/plugin-replace"; to documentation

* Refactoring!

* WIP

* Fixed an issue with events received from callback actors not having the appropriate `_event.origin` set

* Version Packages

* Finish refactoring

* Export createDevTools

* Update packages/xstate-inspect/src/utils.ts

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Update packages/xstate-inspect/examples/server.ts

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Add global shim

* Fix rollup config

* Add null check

* Add changeset and update README.md

* Fixed an issue with some external packages not being bundled correctly into the `@xstate/react` UMD bundles (statelyai#1780)

* Version Packages (statelyai#1781)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Switch to Vue 3 compatibility that has builtin support for the composition API (statelyai#1629)

* build: set Vue 3 as dev and peer dependencies

* refactor: import dependencies from Vue package

* refactor: import test dependencies from Vue package

* refactor: replace Composition API global with Vue

* build: remove Composition API package

* docs: add changeset

* fix: apply suggestion from code review

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Fix tests etc.

* Re-enable husky git hooks

* Remove unnecessary dep & config stuff

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: David Khourshid <davidkpiano@gmail.com>

* Version Packages

* Update README.md

Add Vue 3 template

* Version Packages

* Update docs

* Fixed a typo parenthesis in the docs (statelyai#1798)

* Ensure that services are registered by inspect client. Fixes statelyai#1797

* Add changeset

* Version Packages

* Update yarn.lock

* Update README.md

* `machine.resolveState(state)` calls should resolve to the correct value of `.done` property now (statelyai#1816)

* Version Packages

* Update resources.md

* Update resources.md

* Create deno.md (statelyai#1830)

* Create deno.md

Just wanted to mention how to get XState working on Deno.  Not sure if 'recipes' is the best place, but not sure of anywhere better?

* Update docs/recipes/deno.md

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Update resources.md

* Update resources.md

* Update resources.md

* Remove RestrictedActions

* Add model.reset()

* Revert changed types

* Fix TransitionsConfigMap

* Fix types in tests

* Remove unused function

* Add changeset

* Revert types

* Version Packages

* Add useMachineObserver

* Add tests

* Update resources.md

* Update resources.md

* Updated dependency versions

* Improved `.matches(value)` inference for typestates containing union types as values

* Changed minimum @types/jest version to 24.0.23

* Fix a bound TTypestate not being able to satisfy the default value

* Copied yarn.lock from master and then ran yarn

* Update resources.md

* Fsm actions no longer merged.

* Added 'service' to returned object

* Update resources.md

* Update .changeset/clean-walls-breathe.md

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Rename useMachineObserver -> useInterpret

* Move useInterpret to file

* Fixed URL to a codesandbox demoing @xstate/inspect using vanilla JS  (statelyai#1878)

It was pointing to TS template.

* Documented using useMachine. Adapted xstate-react examples.

* Added 'Services' section to svelte readme.

* Corrections to svelte readme

* Corrected link in svelte readme

* Remove duplicated import from React in xstate-viz (statelyai#1897)

* Remove React double import

* Add changeset for removing react double import

* Revert "Add changeset for removing react double import"

This reverts commit 859845f.

* Update resources.md

* Update resources.md

* Update immer

* Remove xstate-dev

* Fix TS issues

* Fixing types

* Add changeset

* Update resources.md

* Add support for "internal" transitions

* Update shy-toes-worry.md

* Add changeset

* Update resources.md

* Version Packages

* Update .changeset/afraid-eggs-wonder.md

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Update packages/xstate-fsm/src/index.ts

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Refactor

* Version Packages

* docs: remove Spectrum.chat

& where Spectrum.chat is appropriate, remind that GH Discussions is for XState-specific questions

* Update README.md

* Update README.md

* + discussions link

* replace Gitter "chat" with Discord

* Add useSelector + tests

* Fix types

* Version Packages

* Add test

* Separate useReactEffectActions

* Don't use instanceof

* Add test for comparison function

* Update resources.md

* Add useIsomorphicLayoutEffect + consolidate options assignment

* Update README.md

* Fixed an issue with synchronous initial updates not updating useMachine

* Move implementations update to a layout effect to avoid stale closure problems for layout effects

* Update resources.md

* Update resources.md

* Fix selector subscription

* Don't update guards

* Separate observer subscription

* Update resources.md

* Adds final states to test plan description

* Adds changeset

* Version Packages

* Revert options changes

* Add changesets

* Update useSelector

* Memoize listener

* Update resources.md

* Update resources.md

* Update resources.md

* Update README.md

* Version Packages

* add typestate type to service returned from react/fsm useMachine

* Add changeset

* Fixed @xstate/react UMD build by redeclaring toObserver (statelyai#1950)

* Version Packages (statelyai#1949)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Update resources.md

* docs: add new resource

Github - XState with React and Angular in Nx Workspace

* Update docs

* Update @xstate/react README.md

* Fix README.md

* Update resources.md

Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com>
Co-authored-by: David Khourshid <davidkpiano@gmail.com>
Co-authored-by: Dimitar Danailov <dimityr.danailov@gmail.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jonasholbech <jh@jonasholbech.dk>
Co-authored-by: Sarah Dayan <dayan.sarah@gmail.com>
Co-authored-by: decaylala <decaylala@users.noreply.github.com>
Co-authored-by: Tom Byrer <tomByrer@gmail.com>
Co-authored-by: Hosein <hosein2398@gmail.com>
Co-authored-by: Jim Wheaton <jimwheaton@gmail.com>
Co-authored-by: Luke Karrys <lukekarrys@gmail.com>
Co-authored-by: Chau Tran <nartc7789@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants