🏠 back to Observable

How to debug the right way

Hi @all,

I hope you all had a nice Christmas and also took some time off to relax. I have some free time and want to learn new things. Doing so, i write a lot of buggy code in Observable and i often come to a situation where i want to get some (dynamic) state inside a block.

For example

someBlock = {
    while (...) {
         const internalState = {};
         const res = doThing(internalState);
         // i want to check res
    }
}

I tend to use console.log in those cases but it forces me to open the dev tools and this feels “not right”. So i was wondering if there is an intended way to debug code in this situation that is easier to use.
I am not entirely sure if those situations could always be resolved with better “code planning”.

I hope i am not overseeing something totally obvious and could articulate my problem in a somewhat understandable way…

P.S. to give a more concrete example

{
    // i want to check vec
    const geometry = new THREE.ParametricBufferGeometry((u, v, vec) => { }, 20, 20);
    ....
}

I’ve only ever used a combination of console.log and debugger statements. About debugger: if you have your browser’s dev tools open when a debugger statement is evaluated, the Javascript will pause and you can explore the variables / state in your dev tools.

3 Likes

Adding to what @bgchen wrote, you can wrap debugger; statements in conditions (e.g. to only execute them if a checkbox is checked). Other useful tools are:

  • logpoints, which are managed like breakpoints, but instead of halting they just dump a value in the logpoint scope to the console
  • console.assert(), which is like a conditional console.error() and can e.g. be used for sanity checks in calculations (e.g. console.assert(!isNaN(myvalue), 'got a valid number').

If you want something more integrated, my documentation helper signature has some limited support for tests (a few more examples of its application can be found in my work-in-progress Toolbox notebook.

If you want to monitor values in another cell, there are many ways to go about that:

  • use mutable to update another cell
  • use DOM events and have a cell listen to them
  • set your debug value as the value of a viewof cell and trigger an input event
  • currying a function to perform some logging action before passing parameters on to the original function
  • …

While console.log may not be ideal, it is often appropriate given the debugging limitations of Observable’s generated code. I would also argue that your notebook is the “presentation layer”, and using the dev tools to spot and analyze errors is exactly right. :slight_smile:

2 Likes

Thanks for your nice and detailed answer, especially your argument about the notebook as the presentation layer might be right. Never the less I think it might be potentially awesome to have some sort of interaction between the “dev layer” and the “presentation layer”.
This is by no means a feature request but more an inspiration. For example in Matlab there is the concept of a workspace, where you can see the current state.

workspace_browser

From what i understand this might be similar to how the debugger statement works. But having it as a separate tool similar to history (which is still awesome by the way) is maybe worth thinking about.

I’ve hacked together a very basic draft of such a tool:

4 Likes