Moddable-OpenSource / moddable

Tools for developers to create truly open IoT products using standard JavaScript on low cost microcontrollers.
http://www.moddable.com
1.34k stars 236 forks source link

Changing one line of code makes something unrelated break #865

Closed eltoroit closed 2 years ago

eltoroit commented 2 years ago

Build environment: Windows Target device: Moddable Two, Windows simulator

Description Making a change to one line of code breaks the application on a completely separate part. This has happened in three different parts already.

First Example

I have this code (js4IoT_App\networkHelper.js: 429) that works:

request.responseType = {
    type: String,
    fragments: true
}

I change "fragments" to "chunks" and try running the code again, it breaks with error Z:\ModdableCode\NameTag\js4IoT_App\networkHelper.js (365) # Break: ?.?: no function! on this code:

 if (item.ssid.toLowerCase() == lowerSSID) {

This fails in the Moddable_Two board, but the line that fails is when I am scanning for WiFi access points so I can't test this code in the simulator.

Second Example

I have this code (js4IoT_App\assets.js:185) that works:

if (status.weather?.main?.temp && status.config.location.units) {
    debugger;
    WeatherValue.string = `${Math.round(status.weather.main.temp)} ${status.config.location.units === "metric" ? "C" : "F"}`;
}

I comment out the debugger line and try running the code again, it breaks with the error Z:\ModdableCode\NameTag\js4IoT_App\pageInit.js (21) # Break: pageInit: no function!

This fails in the Moddable_Two board, but it does not fail on the simulator.

Third Example

I have this code (js4IoT_App\pageMap.js:57) that works:

if (content.y > sizes.header) content.moveBy(0, sizes.header - content.y);
if (content.y < this.minY) content.moveBy(0, this.minY - content.y);
trace(`Content: ${content.x}, ${content.y}`, '\n');

I comment out the trace line and try running the code again, it breaks with the error Z:\ModdableCode\NameTag\host\main.js (21) # Break: (host): import apply not found! on this code:

if (Modules.has("js4IoT_App"))
    Timer.set(() => {
        Modules.importNow("js4IoT_App");
    });

This works in the Moddable_Two board but fails in the simulator.

Additional notes:

Steps to Reproduce

  1. If I am testing on the board, I first reset it by running this
    C:\js4IoT\esp-idf-v4.4\examples\get-started\blink
    idf.py --verbose --baud 115200 --port COM3 erase_flash flash monitor
  2. I rebuild the host by running this command: mcconfig -d -m -p [win/esp32/moddable_two]
  3. I rebuild the mod by running this command: mcrun -d -m -p [win/esp32/moddable_two]

Expected behavior It works properly, or if I am writing bad code the error messages should be related to the code that I am changing. It should not break when I comment lines, especially trace() or debugger; lines. Also, if I am writing bad code why does it work on the board and not on the simulator (or vice-versa)

Images See the video for the third example in my next comment.

eltoroit commented 2 years ago

https://user-images.githubusercontent.com/7660838/156890860-168e83d9-92d4-41ac-92c0-3b1aa8c5f79c.mp4

phoddie commented 2 years ago

The behaviors you report certainly seem unexpected. However, it isn't practical to analyze the issues of this complexity without some way to reproduce them.

This fails in the Moddable_Two board, but the line that fails is when I am scanning for WiFi access points so I can't test this code in the simulator.

Wi-Fi scanning is supported in the simulator. @wilberforce and I worked on that. You can run the wifiscan on the simulator to verify that.

I believe this issue is happening because my project is getting large...

Bigger projects are more difficult to debug. Still, we have many extremely large commercial projects that are very stable.

Also, if I am writing bad code why does it work on the board and not on the simulator (or vice-versa)

The simulator is not an emulator: the simulator does not attempt to model every behavior of the target hardware. For example, there are differences in available memory and CPU power. These can both trigger different behaviors that reveal issues.

eltoroit commented 2 years ago

@phoddie those are all valid points, but the project should not fail if I comment out a debugger; or a trace() call. I understand my issue is hard to troubleshoot but I am willing to share my repo if that helps. There are some very specific commits where the code fails consistently.

If it helps, I could try the wifi scan on the simulator to see if the error shows itself, but the other behaviors are consistently failing too.

phoddie commented 2 years ago

...but the project should not fail if I comment out a debugger; or a trace() call

In theory, yes. However, calls to trace are not inert. They change timing and, if they cause any allocations, change when the garbage collector runs. They can make a difference.

You have reported several behaviors. It is impractical to look at the simultaneously. I suggest choosing one that is most reliably causes a failure, documenting the steps, and sharing a test case.

eltoroit commented 2 years ago

I will choose the third example. I will close this issue and create a new one with that.

js4iot commented 2 years ago

@phoddie while preparing the new issue, and running mcconfig and mcrun for the simulator, I noticed the code got rebuilt completely, which was not happening before. The commands for the simulator were being executed quickly without doing a full rebuild, and this could have been part of the issue.

Is there a way to force the simulator to do a full rebuild?

phoddie commented 2 years ago

To remove all the temporary files from a project's build:

mcconfig -d -m -t clean

Then build again as usual. The result should be a clean build.

FYI - details on the -t options are in the tools documentation.

js4iot commented 2 years ago

I had seen that page, but it's confusing because it says the default is all which "performs all steps". So, would it not do a clean every time?

phoddie commented 2 years ago

Thanks! The documentation will be updated to the following.

Build Targets

mcconfig takes an optional -t target argument to specify a build target. The options for the target are:

When the -t flag is omitted, the default value is all.

eltoroit commented 2 years ago

Thank you for updating the docs