JS Party ā€“ Episode #281

Is print debugging good enough?

YepNope: Jerod & KBall vs Amal & Eric

All Episodes

Letā€™s debate debugging techniques! Do you print debug or dive deep into debugging tools? KBall & Jerod argue that print statements are all you need while Amal & guest Eric Clemmons take the other side. Who will win and why will it be Jerod? šŸ˜‰

Featuring

Sponsors

Fastly ā€“ Our bandwidth partner. Fastly powers fast, secure, and scalable digital experiences. Move beyond your content delivery network to their powerful edge cloud platform. Learn more at fastly.com

Fly.io ā€“ The home of Changelog.com ā€” Deploy your apps and databases close to your users. In minutes you can run your Ruby, Go, Node, Deno, Python, or Elixir app (and databases!) all over the world. No ops required. Learn more at fly.io/changelog and check out the speedrun in their docs.

Typesense ā€“ Lightning fast, globally distributed Search-as-a-Service that runs in memory. You literally canā€™t get any faster!

Changelog News ā€“ A podcast+newsletter combo thatā€™s brief, entertaining & always on-point. Subscribe today.

Notes & Links

šŸ“ Edit Notes

Chapters

1 00:00 It's party time, y'all 00:40
2 00:40 Welcoming our debaters 01:01
3 01:41 Amal intros Eric 01:33
4 03:15 Setting the debate stage 03:34
5 06:48 Amal's opening statement 01:40
6 08:28 KBall's rebuttal 02:00
7 10:28 Eric's turn 01:29
8 11:57 Jerod's response 02:52
9 14:48 Amal round 2 00:44
10 15:32 KBall round 2 00:59
11 16:31 Eric round 2 01:04
12 17:35 Jerod round 2 01:21
13 18:56 Amal round 3 01:06
14 20:02 KBall round 3 01:20
15 21:22 Eric round 3 01:13
16 22:35 And the winner is... 00:59
17 23:34 Sponsor: Changelog News 02:08
18 25:42 Real thoughts begin 11:32
19 37:14 How Eric finds bugs 01:31
20 38:46 Bug sources > symptoms 02:49
21 41:34 One thing at a time 00:40
22 42:15 On intuition 03:00
23 45:15 Happy path assumptions 02:43
24 47:58 It's almost always your code 02:36
25 50:34 Check out patch-package 02:40
26 53:15 replay.io 02:38
27 55:53 Time-travel debugging 02:34
28 58:26 Closing time 01:31
29 1:00:04 Outro 01:00

Transcript

šŸ“ Edit Transcript

Changelog

Play the audio to listen along while you enjoy the transcript. šŸŽ§

Hello, internet. Iā€™m Jerod, your friend, and Iā€™m here joined by some master debaters. I have Kball with me. Whatā€™s up, Kball?

Iā€™m looking forward to this one. Hello.

Good to have you. And Amal is back. Whatā€™s up, Amal?

Hey, hey. I need a soundboard effect right now. Like, you know, ā€œDung-dung!ā€ Like, Law and Order meets like Rockyā€¦

Hold tight, Iā€™ll get you somethingā€¦ [We love JavaScript. We addicted to it. We love it all the time. We want it in our veinsā€¦ Give me more. More, more.] Thereā€™s your soundboard for youā€¦

Thatā€™s a new one. Okayā€¦ [laughter] Iā€™ll take it.

Do you remember saying that?

I mean, vaguelyā€¦ But yeah. Alright, Iā€™ll take it.

Thatā€™s a cool one. I like that one.

Thatā€™s a cool one. Thatā€™s a very cool one.

And weā€™re joined by a special guest debater. Itā€™s Eric Clemmons. Eric, welcome to JS Party.

Hey! Happy to be here. Ba ba ba ba bam

Ooh, he brought his own soundboardā€¦ [laughter]

I donā€™t have a soundboardā€¦

Yeah, weā€™ll fix that up in post. So Amal invited Eric to debate with herā€¦ Heā€™s on your team, so why donā€™t you do the proper intro and tell folks who Eric is, so he doesnā€™t have to?

Yeah, Eric Clemmons is like a JavaScript gentleman from Texasā€¦ I donā€™t know if thatā€™s even giving you justice.

Iā€™ll take it.

Heā€™s a huge open sourcer, incredible lead engineer, heā€™s worked a number of places, weā€™ve spent some time together at Stripeā€¦ And heā€™s just kind of just overall ā€“ I donā€™t know, Iā€™m gonna get bleepedā€¦ Heā€™s just a JavaScript badassā€¦ Really into kind of like solving problems when it comes to the developer experience. Heā€™s got some really cool libraries out there. Oneā€™s called click-to-component, and it lets you kind of inspect your elements real-time. Heā€™s got some other really cool utils around testingā€¦ I donā€™t know. Eric is just awesome, and Iā€™ve wanted to have him on the show for a while, and glad heā€™s finally onā€¦ But Iā€™ll let him introduce himself.

Here he is. Did she miss anything, Eric? Anything to add?

I donā€™t think there is. Iā€™m kind of blushing and tearing up at the same time. Thatā€™s really sweet. But yeah, the DX part is a very huge aspect of it. Anywhere that thereā€™s friction in the experience, gotta burn it with fire. You know, kind of like console.log, and print debugging, that sort of thingā€¦ [laughter]

Ohh, heā€™s beginningā€¦ The debate hasnā€™t begun yet, Eric. So for our longtime listeners ā€“

Those are baked. Why you gotta add friction?

Kball, the debate hasnā€™t begunā€¦ Letā€™s hold it back. Theyā€™re chomping at the bit here. So longtime listeners know that we routinely do debate episodes, where we pick a premise, and then we assign people to a side. They donā€™t get to pick their side, because that wouldnā€™t be as funā€¦ And we debate whether or not that premise is true or false. We donā€™t call it true or false, we call it Yep and Nope, because of our friend Alex Sextonā€™s classic yepnope.js feature detection library from way back in the jQuery days. Alex was actually one of the original panelists on JS Party, so itā€™s a nod to him. Itā€™s called a Yep/Nope, and weā€™re gonna play that today.

Todayā€™s premise, if you havenā€™t guessed already, is about debugging. And the question that weā€™re trying to answer is ā€œIs print debugging good enough?ā€ So print debugging - what is that? Well, thatā€™s anytime that youā€™re just putting print statements in, however you happen to do that. Most likely, in our world, console.log. It used to be alert debugging; youā€™d have an alert statement, and you would try to put some stuff in there, and itā€™d pop out and youā€™d read it and itā€™d say ā€œobject objectā€. And then you wouldnā€™t have any help from that whatsoever. But console.log is significantly better than the bad old daysā€¦ But is it enough? Is print debugging good enough? Arguing the positive will Kball, and your humble moderator, even maybe not so humble moderatorā€¦ Me. I will be arguing today, because scheduling conflicts. So thatā€™s the Yep side.

And on the Nope side, arguing that print debugging is not good enough will be Eric and Amal. We do this semi-formal, so we actually have a timer, and we have a buzzer, but we also have a shoestring budget, so our buzzer noise is Chris Hiller saying Wut. So if you hear this sound, [Wut?] your time is up. And if you donā€™t stop talking, I will hit that button profusely, until you do. I might even do it to myself, which would be weird.

I might just break out into song, if you knowā€¦ What, what, what-what, whatā€¦ You can put a beat to that.

Iā€™m never gonna stop you from singing, Amal. Iā€™m just sitting here in anticipation, soā€¦ Whenever you break out into a song, Iā€™m here for itā€¦ Because we need more soundboards.

Eric, do you beat-box? Yā€™all could do a duo.

Go, Amal.

Oh, goshā€¦ On-demand isnā€™t the way it works. Itā€™s when it comes. It comes in its own schedule.

She may be the Beyonce of the web platform, but sheā€™s not actually Beyonce.

Right, right. That is very accurate, on many levels.

Thatā€™s fair.

Yeah. But thereā€™s some guitars behind Eric, for those of you listeningā€¦ Eric plays a lot of music.

Thatā€™s true. Eric, are you musical?

I am. This was part of the compromise to move to Texas from like Seattle, was I got to bust out all my musical instruments again. In Seattle I just didnā€™t have the room for the instruments, but now I do.

I was gonna say, youā€™ve got a drum kit back there as well.

Yup. My very first drum set Iā€™ve found when I was six in the church dumpsterā€¦ So I havenā€™t been able to quit playing drums since.

Wow. What kind of music do you play?

Honestly, just anything Iā€™m listening to in the car that sounds like it has a good beat, I come home and basically just replay it.

[06:16] Very cool. Well, we will cue you later to begin singingā€¦ Iā€™m sure Amal will work you in. Letā€™s start this debate before we lose all of our listeners, and the debate hasnā€™t begun. So two minutes on the board, okay? Youā€™ll have two minutes to state your case, and then weā€™ll rotate back and forth between teams. So we will start with our guests - well, our guest is Eric. Amal, youā€™re on his team. Ladies will go first, so weā€™ll let Amal go firstā€¦ And you are arguing ā€œNo, print debugging is not good enough.ā€ Thereā€™s two minutes on the board. Amal, letā€™s hear it.

Thank you, Jerod. And hello, listeners. Print debugging is certainly one way to do it. Itā€™s not wrong. But the web has evolved. We have so many better ways to debug and inspect. Thereā€™s lots of engineers that have created awesome tools and protocols that allow you to kind of connect with your code in a more intimate way than just logging statements.

So why would you limit yourself to just a bunch of logs, which arenā€™t always even ā€“ you never know where youā€™re even logging from sometimes, unless youā€™re in a Node environment and you can print a context as wellā€¦ And so logs are great, but thereā€™s so much more. And hopefully, Eric, and I will be getting into all the thingsā€¦ And with all the new features that have come into Chrome Dev Tools, which is kind of a shared universal protocol between a lot of browsers - why limit yourself to just logs? You can do things like even mock your HTTP headers now.

So weā€™ve gone way beyond the days of just kind of breakpointsā€¦ Weā€™re now able to manually trigger errors, and say, ā€œHey, I want to kind of always have this network request fail, and so letā€™s see how resilient my app is for when this network request fails.ā€ You can do all kinds of things, like conditional breakpoints, you can watch all the variables in your execution contextā€¦ Thereā€™s so much, so why limit yourself to just logs? Thereā€™s more than logs.

[Wut?] Alright, very good. Opening case by Amal. Kball. Make our opening case for us, please.

Alright. Amal, in previous debates, you have said something along the lines of ā€œJust because you can do it doesnā€™t mean you should do it.ā€ You have argued about the dangerous path that extensive developer experience-focused tooling React and other things have led us towards, and how those are poisonous for the web. And so I want to say, as developers, weā€™ve got to master the basics. Weā€™ve got to stay with whatā€™s real, whatā€™s built-in, what works wellā€¦ And when it comes to debugging, that is console.log or printf debugging. You know, itā€™s a ā€œkeep it simple, stupidā€ type of situation, right? Like, keep it simple. This is all you need.

What are you doing in debugging? Youā€™re trying to understand the state of things as theyā€™re going alongā€¦ And you said something like ā€œYou never know where youā€™re logging from.ā€ Have you ever heard of logging ā€œI got hereā€? Thatā€™s a core to printf debugging, ā€œI got here.ā€ I got here, too. Keep it going.

So fun.

But in a slightly more serious frameā€¦ There are so many different environments that youā€™re gonna want to debug in. Sometimes youā€™re able to debug something totally locally, other times a problem doesnā€™t emerge until youā€™re out in production, youā€™re in a distributed application, you have race conditions, and all these other thingsā€¦ And the thing that all of these fancy debugging tools do so much of the time is they will freeze you in time. But now you have gotten rid of your race condition. Your bug goes away, you get a heisenbug, and if thatā€™s how you teach yourself to debug, youā€™ll never be able to use the tooling that happens in real time, flowing out data, and giving you that availability. Console.log becomes observability in production. It becomes, ā€œLetā€™s understand the state of many things happening at onceā€, and it becomes a foundation for you to debug all of those complicated environments and other situations that show up outside of your packaged development environment.

[10:13] [Wut?] Alright, perfectly coming in on time, like the pro that he is. Llike the winner that heā€™s gonna be. Eric, itā€™s now your turn to spend two minutes talking about logging or not logging. Go.

Yeah, I mean, Kballā€™s not wrong.

Good startā€¦

I mean, if you have like one tool in your tool belt, that tool looks pretty good. And it pays to be proficient with a lot of other tools. Because I mean, if we talk about logging - yeah, thatā€™s one piece of it. But itā€™s missing the rest of the history of how we even got there, especially if weā€™re talking about the userā€™s machine. If youā€™re console-logging, youā€™re on your machine. Youā€™ve already gone into the codebase. What about everything else that happened before then? What made their environment unique, those race conditions that only they got to see, because they have a different environmental config, or a different browser, or maybe even like a different backend configuration that youā€™re just not aware of, that doesnā€™t match what youā€™ve been testing or developing against?

So yeah, itā€™s a tool weā€™ve had, thereā€™s not a lot of friction to it, it kind of reminds me of that meme with this cavemen with a square wheel, and someone else offers them a round wheel, and theyā€™re like ā€œNo, thanks. Weā€™re too busy.ā€ Yeah, if you like to be effectiveā€¦ I mean, we could learn from other people in the industry. For example, Next.js - big topic - has just launched their app routerā€¦ And Tim Neutkens has even mentioned that like thereā€™s 20 super-complicated bugs that would have taken days to reproduce and actually investigate if it wasnā€™t for improved logging tools. So half of the story is actually whatā€™s going on on the userā€™s machine who isnā€™t a developer, who doesnā€™t have console.log developing. So itā€™s not ā€œnoā€ to debugging, but maybe just grabbing the wrong tool for the job.

[Wut?] Alright, I will now respond. Itā€™s interesting, Eric, that you mentioned improved logging toolsā€¦ Weā€™re all for improved logging tools. We want the best logging tools that there are. But at the end of the day, these are logging tools, and logging is good enough. Print statements are good enough. Kball mentioned the KISS principle, right? Keep it stupid simple. Iā€™ll also mention this - you want to be able to learn something thatā€™s transferable. So I have logging skills, and Iā€™ve worked in many different areas, with many different languages, and many different runtimes, and my ability to print stuff has paid off everywhere Iā€™ve gone. Now, I also learned a little bit of GDB, the GNU Debuggerā€¦ And let me tell you how inscrutable that tool is. And I learned how to use it, and I got some value out of it, and then I went into the web browser and I realized 0% of my GDB skills actually transfer into the web browser. And so now I invested a bunch of time learning a very sophisticated, powerful power tool, and I couldnā€™t take that anywhere.

Now, I could dive into Chrome DevTools and learn all the intricacies of Chrome DevTools, and maybe theyā€™ll change, and my knowledge will be gone. Or Iā€™ll switch to the backend, and now all of a sudden I donā€™t know the backend tools. And so thereā€™s a real value in simple tools, easy to learn, easy to transfer, and good enough to get the job done most of the time.

Now, I still have 40 seconds left, so I will start our classic move of appealing to authority, and I will read some quotes at this time. ā€œI donā€™t like debuggers. Never have. Probably never will.ā€ End of quote. Linus Torvalds.

ā€œAfter over 30 years of programming in assembler, Fortran, C, C++ etc. I feel no desire to use a debugger.ā€ Neal Butterworth.

ā€œIā€™ve met junior developers who feel like they donā€™t know how to use a debugger, or they donā€™t know what theyā€™re doing, and they just put print statements out. Thatā€™s completely legitimate. In fact, it tends to be my go-to thing doing that.ā€ Matt Ryer. [Wut?] And my time is up.

Thus concludes round one of our debate. So far, the Yups have it, the Nopes are struggling, but weā€™ll see what happens in round two.

Amal, weā€™re back to you now. You have one minute; you can answer any of the things that weā€™ve said, or you can just go off and say whatever it is you like, for one minute.

[14:13] Can we first start by acknowledging that the moderator is the non-neutral party? And so you get to add to the hype factor of your team, which really ā€“ I mean, letā€™s be honest, is it a tool? Is logging a tool? Or is it just like a thing?

Wait, is this your time? Okay, Iā€™m gonna start your time? Youā€™re just launching into an argument before your time startsā€¦

[laughs] Iā€™m rolling it.

Okay. Your timer is going, Amal.

This is preparation for the reality of the corporate world. The moderator is always biased. [laughter]

Right, right. Itā€™s a hard, cold lesson in capitalism, or something. But okay, so yeah, logging, as Eric mentioned - not wrong. Itā€™s certainly a thing that you could do. But given the variety of options that you have at your disposal when trying to problem-solve, why limit yourself to the most rudimentary option?

So when you, for example, are able to actually stop at a breakpoint, and inspect your code, and see where ā€“ you can look at the call stack, youā€™re able to look at not only how you got here, but where, because of the variables and all the things in scope, where youā€™re going to potentially head to nextā€¦ [Wut?] Thereā€™s so many other options. Why limit yourself to logging? I mean, for me, thatā€™s the ultimate argument. [Wut?]

Alright. Kball, one minute.

Letā€™s be real - debugging is a means to an end. The point is not the debugging process, itā€™s to find that stinking bug and get rid of it. And you could do the classic developer thing, which is spend your three weeks learning your tools, digging in, getting it set up, perfect debugger, learning the changes that happened since the last release statement, and then youā€™re one day to debug. Or you could use the same tools that have been working the same way since the dawn of programming, and get to your bug a heck of a lot faster. And I know, as developers, we love to dig into fancy tools. Like, thatā€™s one of the reasons we got into development. And itā€™s great if youā€™re doing it for fun. But if your goal is debugging, and getting to the end of that bug, stick with the tool that you already know, that works well, thatā€™s going to be transferable, as Jerod said, and fix your bug that much faster.

[Wut?]

ā€¦or slower.

Coming in right on time. Alright, Eric, your turn.

Right on. I think itā€™s wise for us to recognize that code is a means to an end. But itā€™s also pragmatic to say that how we work, how we do the job that people are paying us to do, the faster we can shorten that time between ā€œThatā€™s not doing the thing that we paid you to do. Make it do the thing that we paid you to doā€, is in the best interest of the company, and also kind of what makes you valuable as an employee.

So there are going to be non-transferable skills at any sort of job - who to talk to, what the bug tracking system is, how the release management process works, what the codebase even looks like; is it going to be different from the last place? Thatā€™s largely non-transferable.

So if we level-up our tools to be able to get us to ā€œWhere is the problem actually happening?ā€ and let us get us into a reproducible state faster, as fast as it was for the user to experience that bug, thatā€™s going to shave off a ton of time of us trying to set up an environment, us trying to do console.logging replaying, and constantly changing our print statements until we can actually identify where it was, where we could have had the information to begin with, versus throwing it away. [Wut?]

One minute for meā€¦ I will now continue reading quotes off of the internet. No, Iā€™m just kiddingā€¦ [laughter] But I will mention that I have polled the audience, our Changelog community, and 55% of respondents mostly use print statements. And only 45% mostly use a debugger. So thereā€™s wisdom in the crowd, and proficient, crowdly devs find print statements to be good enough. As do I.

[18:00] So I will now tell an anecdote of my life. I have been developing software for 20+ years, various stages of qualityā€¦ And so that can be up to the reader of the code, I suppose. But Iā€™ve put up production systems, and Iā€™ve built all kinds of thingsā€¦ And like I said, back in the day, I learned GDB, and I learned how to use a debugger, and I see the value in it. Ultimately, the ROI on that tool is lower than Iā€™m willing to invest. And so as I move on in my life to the next phaseā€¦ Oh my gosh, I just got started. Hold on, I now allow myself 20 more secondsā€¦ [laughter]

Just gonna lean on that scale a little more thereā€¦

Yeahā€¦ Iā€™ll stop, because I am a fair moderator. Iā€™m not biased. Iā€™ll stop right there. But yā€™all know where I was driving with that little story. And I was going to a really good place. Okay, weā€™ll give Amal one more minute. Do you want another minute? Have you got anything else to say? Or are you all out of arguments?

Yeah, sure.

Alright, go ahead.

I mean, I feel like Iā€™ve been arguing against logs, but really what I should be doing is arguing for all the things that you can do beyond logging. So look at how the web has evolved. So we have tools like Lighthouse, that allow you to kind of debug all kinds of issues in your application real-time. And thatā€™s something that you canā€™t do from a logger. You can record your performance, you can look at your heaps and get snapshots of kind of how much bandwidth youā€™re utilizing. Or device compute youā€™re utilizing. You can figure out how long API requests are taking. Thereā€™s all this kind of conversational ā€“ thereā€™s a kind of a huge conversational element, and almost like a query-like elements to debugging, which you canā€™t get from just plain logs. [Wut?] And so yeah, why limit yourself?

Kball, one more minute.

The world is ā€“ itā€™s a big, big place out there.

[Wut?] Listener, disregard the last thing Amal said. It didnā€™t count. It was outside of the time. Okay, Kball, go.

So I think fundamentally we might be disagreeing about what logs are. So when I want to debug something that happened to a user in production, I go and I look at the information I have about what happened to them. Itā€™s in my logs. I go and look up the exception trace. What was the exception that it threw? Thatā€™s a log. I go and look at my observability of like ā€œOkay, how many other people have hit this? What are the data on that?ā€ Thatā€™s an aggregation of logs.

Fundamentally, logs is whatā€™s underneath all of these advanced tools. And if we start from thinking about what data do we need to log - and I donā€™t just mean ā€œWhat data do I need to log now to debug this problem that Iā€™m doing now?ā€ But if I start from a log-centric mindset, I am thinking about ā€œWhat do I need to be logging throughout my applicationā€™s path, such that when something goes wrong, I have the information that I need in order to track down what it was?ā€ Because I canā€™t predict what is going to go wrong, or when itā€™s going to go wrong. I donā€™t have a controlled environment for when things go wrong for usersā€¦ [Wut?] So I need to be thinking from a log mindset what needs to be there for that future self.

Log mindset.

Do not pay attention to the last thing Kball said, unless it was really good for you, then go ahead and keep it. Alright, Eric, final statements. Youā€™ve got one minute. Go, sir.

Yeah, I mean, if weā€™re gonna talk about how we store data, like the .har files that we record in browsers, and everything we store, we might as well say yup to JSON, and Iā€™ll be on the same page and end the show now. But itā€™s more to that. If we look at the patterns of when logging is good enough, weā€™re seeing engineers keep ā€“ like that quote from earlier, just like ā€œI see junior engineersā€¦ā€ Yeah, because itā€™s a low-level tool and primitive. You learn that day one of programming. But if you want to stay at a junior-level debugging experience, then thatā€™s perfectly fine. But as we improve and grow, one of the things that we should be doing is having faster, rapid iteration loops, and a lot of that comes from leveraging the tools that are applicable to the environment weā€™re in, thatā€™s in the stack that weā€™re in, and the company that weā€™re in, and using those tools so that way we can go from zero to fixed as soon as possible. And if that means moving console statements around, you can just look at the number of typing, like how many key presses youā€™ve been using to debug something to realize that this is kind of an inefficient process. If you could have gone to what the end result is faster, where that undefined came from, youā€™d be done. [Wut?]

[22:34] Okay. So as moderator, I will defer my final minute in order to tally the resultsā€¦ And we had ā€“ letā€™s see, carry the threeā€¦ Okay, over hereā€¦ Wow. After this scientific result calculating, it turns out that for the first time in Yup/Nope history Jerod didnā€™t win. We all win. [Win, win, win, win, win. We all win.] So congratulations to both sides for presenting excellent cases. We all win, guys. How does it feel?

Not riggedā€¦ [laughter]

Alright, well, dear listener, obviously, you have a real winner in mind, and so you can email us, you can tweet at us, and you can just tell us that it was me, and then weā€™ll feel better about it. But Iā€™m not going to declare myself the winner, because Iā€™ve transcended such things. But finally, at the end of the day, weā€™re happy, because we all are going to find that stinking bug. [Ah-hah! Iā€™ve found ya, ya stinkinā€™ bug!]

Break: [23:35]

And thus ends our Yup/Nope debate, but weā€™re not finished talking. So letā€™s now just discuss freely amongst ourselves - no timers, no moderator, no Jerod winning everything, but just giving you guys that olive branch and saying that we all won, even though we really know what happenedā€¦ Instead of all that, letā€™s just discuss debugging tools, techniques, what do you all doā€¦ Are you representing the side that you actually believe in? I will say that I do use console logging for most situations. There are obviously scenarios where you get a particularly sophisticated bug, and you do need a little bit more firepower in that circumstance, and so I will move on from thereā€¦ But I do find that for most things, itā€™s enough to use console.log. And because of the power of the dev tools, console.log has so many features, like right-click ā€œStore as global variableā€ - thatā€™s basically print debugging, but itā€™s going beyond print debugging, isnā€™t it? ā€¦because now youā€™re actually interacting with the environment as it is, and thatā€™s incredibly useful for diving into an object and seeing what data is there and all that. So thatā€™s my actual take, because I do mostly do print statements, but I also like to hop into the runtime and stop things, and try things when itā€™s sophisticated, or difficult, or when print statements arenā€™t quite good enough, even though mostly they are. So thatā€™s what Iā€™m thinking. Eric, whatā€™s your stance? How do you debug? What are the tools that you use in these circumstances?

Itā€™s a lot of the same. And really, the biggest problem isnā€™t so much of where to put that print statement, or if Iā€™m going to run Node Inspector, and debug this thing in Chrome, and set a breakpointā€¦ I find actually breakpoints be more of a hindrance; Iā€™ve recently learned how to do like the variable watching, which has been way more useful for meā€¦ To just say, ā€œLet me know what this value is and how it changes.ā€ Weā€™ve talked about race conditions earlier, Kballā€¦ Itā€™s kinda like that example, is I want to see the thing run and play, and then just get into the iteration loop. But thatā€™s not really where the friction is. Most of the friction for me is trying to get to the reproducibility part; itā€™s all the stuff outside of my control. Iā€™ve spent so much time over my career trying to have reproducible environments, and trying to like log in as and impersonate some special user sessionā€¦ And that ā€“ I mean, thereā€™s tools solving for that now, but I see that as being where like most of the ā€œWorks on my machineā€ issue is coming from; the code part has become easy to actually debug once you have reproducibility.

Yeah. Good point. Reproducibility is killer. A lot of the work is just getting to that spot, or finding that spot. Yeah.

Yeah, I would second that breakpoints can be annoying AF. However, helpful AF. However, I think for me that ā€“ I didnā€™t want to argue this earlier, because it wasnā€™t team logā€¦ But console.log has really gotten very souped up; thereā€™s really smart things you can do now. Thereā€™s console.assert, that lets you kind of do a conditional console.log, where you can say - your first parameter is what your truthy or falsy value isā€¦ So you can do a check to say ā€œIf this is true, then do a log.ā€ So if you donā€™t want to end up ā€“

Yeah, that is such a useful tactic.

So good.

Itā€™s so helpful.

Yeah. I mean, itā€™s way better than a breakpoint, because then you donā€™t have to find ā€“ thereā€™s all this context switching, right? So thereā€™s that, and then just being able to kind of also view your data in a richer way, like things that youā€™re logging, with console.table, console.dir, whether youā€™re trying to kind of open up arrays, or objectsā€¦ Thereā€™s nice ways to kind of quantify the data that youā€™re printing. So logs are great, but for me, thereā€™s just nothing more beautiful than also just typing debugger-semicolon and just letting your code rip, like run. And being able to just kind of inject a breakpoint from code. I think thatā€™s also just really nice, and something that I donā€™t see developers utilize enough; you donā€™t have to kind of futz about.

However, I think some of our pain points around using breakpoints have greatly smoothed over in the recent versions of Chrome. Everything from kind of like auto-ignoring third party scriptsā€¦ Like, donā€™t you hate it when youā€™re just trying to like walk, get to a place, and then itā€™s like ā€œWhy am I in all this obfuscated JavaScript that I havenā€™t written? Get me out of here.ā€ So being able to ignore third-party scripts; and then being able to even just click on entire directories from within your debugger and just say ignore; like, your Node modules, or any other directory that you want to ignore.

So thereā€™s lots of kind of nice UX improvements, I think, that have happened around working with breakpointsā€¦ So if itā€™s been a while, or if youā€™ve hated breakpoints your whole life, Iā€™d say give them another chance. I think thereā€™s a lot of really nice improvements that have come in over the past year and a half.

[30:35] I think itā€™s also worth pointing out that thereā€™s kind of different kinds of debuggingā€¦ Because a lot of the debugging that I do is actually just development. So Iā€™m actively coding, and Iā€™m just like shaking out bugs while Iā€™m coding. And so in those cases, console.log is darn near all you needā€¦ Because youā€™re like coding, youā€™re doing a thing, youā€™re like ā€œOkay, this is not working. Whatā€™s wrong with this object here? Okay, Iā€™m gonna print it, Iā€™m gonna look at it. Okay, no wonder; it didnā€™t have this property. Okay, go back to my code.ā€

And so Iā€™m debugging while I code. In that case, I donā€™t really find ā€“ I do like to stop the world every once in a while, but I donā€™t find it to be super-useful. But then you have the one that is like ā€“ somebody opens a ticket, and itā€™s like ā€œOkay, this ā€“ā€ And it comes back to what Eric was talking about, with reproducibility. Itā€™s like, this bug exists in production, and it exists for this user, at this time of day; they happen to live in San Diego. But the production database is in Tokyo, or something. And now youā€™re like ā€œOkay, Iā€™m not like actively doing stuffā€¦ Iā€™m just here to solve a problem. Where do I start?ā€ And a lot of the difficulty is, ā€œWell, how do I get my system that Iā€™m working on to look like production, to look like that user?ā€ And Eric, you mentioned shadowing techniques, or like login as, or masquerading as a user kind of things, which - that stuff is very valuable, but you end up having to develop that yourself, or you have to like buy a system that allows you to do thatā€¦ So a lot of times, I think thatā€™s the really complicated part of debugging.

Having a local production environment, something that connects to the production databases, but lets you reproduce in a local environment is super-helpful for that. That was something that I hadnā€™t seen that much, and then my last job had that, and I was like ā€œOh, this is really cool.ā€

Are there guardrails around that?

In that case, there were. So the default was you were in read-only mode. So you could log in, youā€™re accessing it, but youā€™re read-only; writes are just ignored. And that was implemented at the data layer, so it would have been very, very hard to mess that up. That was the biggest guardrail. There were others. There was like a banner on, ā€œYou are in production modeā€, or whatever. ā€œBe careful.ā€ Things like that.

So thatā€™s something that somebody at your previous employer put together, right?

They built, yeah. And it was easier to do in that environment because they were operating in a world where even the development environment was connecting to a cloud databaseā€¦ So you didnā€™t have this local versus cloud split in the same way. So the environmental change was not that differentā€¦ Though if youā€™re already implementing a cloud environment for your production, and youā€™re already thinking about how that works, adding a local prod version of that, so long as you have your tunneling things figured out, which is kind of the key question, is like permissions and tunneling, and how are you doing itā€¦ We were operating in a trustless mode for everything; we didnā€™t have, ā€œOh, this is a trusted network and this is notā€, which once again, that setup makes that a lot easier to generalizeā€¦ If youā€™re having the ā€œOh, weā€™re inside the cluster, so weā€™re trustedā€ type of setup, itā€™s a lot harder to implement a local production environment.

Coming back to this question of debugging - youā€™re totally right, Jerod, a lot of debugging is in flow with development. When I think about debugging, I donā€™t even think about that. Thatā€™s just like, thatā€™s development. Okay, Iā€™m working on that in whatever the tool is for the job. And when I think about debugging, a lot of times the things that I would get brought into, especially my last few positions, itā€™s like ā€œThis is something that happens somewhere in production, and we donā€™t know why, and we donā€™t know what reproduces it.ā€ So sometimes itā€™s figuring out how do you get your reproducibility, and in some cases there is no way to get to reproducibility. It only happens when certain things align.

[34:15] And so then it really becomes about how do you ā€“ it is this observability question, extension of logging, of like ā€œHow do you get enough stuff in place in your application environment, so that when the problem happens, the information is captured, enough information is captured that you can reproduce what actually went on there?ā€ And I do think in that situation ā€“ the ā€œconsole.logā€ debugging is a closer mindset to that, but itā€™s reallyā€¦ Like, weā€™re starting to talk about observability, and this question of ā€œHow do you log out sufficient application state to understand what went on when youā€™re looking at it after the fact?ā€, rather than ā€œI have an environment where Iā€™ve reproduced an issue, and Iā€™m doing things, and Iā€™m able to tinker and go back and forthā€, which is where both the inflow of development debugging happens, and also where a debugger or tools like that tend to be very useful.

Thatā€™s a really good point, Kball. I think for me, just listening to you, I was reminded of console.trace; something else that Iā€™m ā€“ at one point in my career I remember I just like substituted all my logs for traces. It was super-annoying, but it was helpful. Annoying because you get this long outputā€¦ But yeah, itā€™s nice to be able to see how you got there. I forgot that you canā€™t actually do that with a log.

Is that the same thing where it gives you a full stack trace? What does console.trace do?

It basically it prints out, you know, if you give it a thing to print out, but then after that, you see how you got here. So we are in this function, and before this we were in this function, and this functionā€¦ So itā€™s kind of like your stack trace, but it gives you that, I donā€™t know, five or six lines deep of everything that happened; what contexts were you in before you got to this context, basicallyā€¦ Which is very, very helpful.

But I think for me, debugging is just about piecing together the map of your state, your application stateā€¦ And I remember the first time I debugged, it wasnā€™t even in a JavaScript context. It was like in Python, and Rubyā€¦ All these ā€“ similar to the debugger statement in JavaScript; you know, in those languages you can put like a binding pry, or IPDB

Right. Pry is a tool in Rubyā€¦

Exactly. And so you immediately open up this repl context where you can actually query and see ā€œOkay, what is my application state right now?ā€ And I think for me, thatā€™s the secret sauce power of being able to actually stop and pause in an execution context, is actually understanding ā€œWhat are the values of all these variables right now, and whereā€™s the disconnect?ā€ Because youā€™re there because something isnā€™t happening as you expect it to be. And so I think thatā€™s very useful. And I think tools like TypeScript have reduced the need for some of that, to be honest. I think thereā€™s a little more predictability in our overall state because of TypeScriptā€¦ But still.

But still.

*bleep* still happens, yes.

So Eric, in your work, when you get a ticket, or you get an issue, or a colleague comes to you and says, ā€œHey, Iā€™ve got this bug. I canā€™t figure it outā€, what do you generally do? Where do you start? What are the steps that you take to get through that?

The very first thing is always ā€œAlright, show me with a video, a reproducible repoā€, something like that. Itā€™s usually ā€“ itā€™s kind of like ā€œHave we logged enough?ā€ If I find myself going to Data Dog to look at raw logs for what happened, I already know Iā€™m going to be having a bad day. Iā€™m like ā€œThis is too far in. I know Iā€™m missing off on network requests, and everything.ā€ Yeah, but once you get into ā€œOkay, I can point to where the problem isā€, itā€™s kind of like normal development, like you mentioned, Jerod. Weā€™re constantly logging, seeing what the state is of how somethingā€™s workingā€¦ And I have a nagging voice in the back of my head thatā€™s like ā€œYouā€™re putting all these console.logs in here.ā€ And I have a personal rule that says ā€œItā€™s okay for bugs that happen once.ā€ Hopefully, employers arenā€™t listening, butā€¦ You know, ā€œItā€™s okay for bugs happen once, but just not twice.ā€

[38:14] And so anytime I do something ephemeral, like putting into console.log, that ultimately gets deleted from that bug, that nagging voice is saying ā€œWell, you could have been doing test-driven development for this, right? Couldnā€™t this have been a test to make sure it doesnā€™t happen again, instead of you just logging out, ā€œOh I wasnā€™t doing a typecheck here,ā€œnNow the undefined isnā€™t happening, and I fixed it.ā€ So thatā€™s usually how the flow goes, is identification, reproduction, and then whether or not that fix is going to be resilient to more code changes in the future.

I think thereā€™s something really important in that, which is trying to identify not just what was the immediate source of this bug, but what is the underlying fragility, whether itā€™s in our processes, or our systems, or whatever, that led to this bug being possible. Ad bugs are gonna happen, we are all human, humans make mistakesā€¦ But you can often start to detect things like that, where you might say, ā€œOh, weā€™re using JavaScript instead of TypeScript, and so we have this whole set of things.ā€ Maybe if we move to TypeScript, this wouldnā€™t be possible.ā€ Or we have a set of types that are not sufficiently constrained here, and so weā€™re running into challenges. Or maybe you can say, ā€œOh, this system is developed in a way or works in a way such that it results in lots of buggy code. Itā€™s really hard to work with, and people tend to misinterpret it because the API is shaped funnyā€, or something like that. Okay, letā€™s identify those patterns that lead to the bugs, and then say, ā€œOkay, when we have time, or let us make some timeā€¦ How do we address that systemic issue so this class of bugs completely disappears? ā€¦not just letā€™s whack a mole them down as they show up.ā€

Yeah, well said. And I think, Eric, your point about adding tests - I mean, thereā€™s no better time to add a test than when youā€™ve just fixed a bugā€¦ Because now you know exactly one thing that could go wrong, and you can add a test that just makes sure that at least that one particular thing is never going to go wrong again. So even if you donā€™t TDD it, you can at least add a regression test after the fact, that just tests for that bug. But it actually is a good way to debug, is once you know what the problem is ā€“

I was gonna say, even better is before.

Yeah. You write that as a test, and then you make the test pass, and life is good from there. I will say, when it comes to actually identification - so Iā€™ve worked on a lot of network systems, Iā€™ve worked on a lot of web apps and stuff, and there are certain people that you work with over time who are just really good at findingā€¦ You know, a lot of times youā€™ve got to find the bug; thatā€™s all the work. So reproducibility is the name of the game; itā€™s like ā€œHow do I reproduce this?ā€ And sometimes you can just get yourself in this general arena of the bug, but youā€™re not really sure exactly whatā€™s going wrong, but you know itā€™s not this subsystem, or that subsystem. Itā€™s over here in this subsystem, and youā€™re trying to feel around in the dark. Depending on your tooling, it could be more or less dark, but a lot of times it is, for what exactly is causing that circumstance. And people that Iā€™ve learned from that are really good at that - some of it eventually expertise turns into intuition, and theyā€™ll just kind of know whatā€™s wrongā€¦ And youā€™re like ā€œHowā€™d you do that?ā€ and they canā€™t describe it, and youā€™re like ā€œDang.ā€

[singing] I feel it in my fingerā€¦

Yeah, exactly.

No, Iā€™m just kidding. See, Iā€™ve found an opportunity to singā€¦

Oh, no, but then you stopped short. We want you to launch into it. Eric will grab his guitar, and then Kball and I will just dance.

Yeah, exactly. [laughs] Yeah, weā€™ll just be squashing bugs.

Weā€™ll have an actual partyā€¦ But if you donā€™t have that intuition, Iā€™ll say this - only change one thing at a time. Thatā€™s how you find it. You keep everything ā€“ like, caeteris paribus; everything else is the same. Iā€™m going to change one input, Iā€™m gonna test it. Then Iā€™m gonna put that input back to what it was, and Iā€™m gonna change my next thing, and Iā€™m gonna test it.

[41:51] Never change three things and then see ā€œOh, Iā€™ve reproduced it all of a sudden.ā€ Well, which one was it?ā€ ā€œI changed three.ā€ ā€œThose three together? Or was it two of the three? Or was it just that one?ā€ ā€œI donā€™t know.ā€ And now I have six more things I have to go try before I actually have confidence that the bug is fixed. So thatā€™s like the best, for me, advice; when you donā€™t have the intuition, eventually youā€™ll get there, I think, if you develop long enough. Just change one thing at a time, until you land on it.

When you mentioned that intuition - how much of that is the building up of the skill of being able to identify where problems can happen, those types of problems, the entire classes that we ideally want to remove? Or is it intuition of how the system works? Like, where the systemā€™s fragile, where the system is resilient, that sort of thing.

Yeah. I would say that Iā€™ve seen it be both; itā€™s kind of hard to actually dissect that and say either or, because Iā€™ve been with people who are deeply into a system, like they know that system inside out. And thatā€™s the guy or gal that youā€™re gonna go to with the bug, because they know the system. And then Iā€™ve also ā€“ I have one individual in mind specifically, whoā€™s just good at finding bugs in anything. And so it didnā€™t matter if he has the domain expertise, or he wrote that subsystem or not, itā€™s like ā€œHey, George, or whateverā€, Iā€™ll keep it anonymous, to not embarrass somebody with complimentsā€¦ Heā€™s just good at debugging things generally; itā€™s like, he just knows how to ā€“ I donā€™t know. So Iā€™ve seen people that are kind of in both camps. Does that align with you guys, orā€¦?

Yeah, thatā€™s very aligned with my experience. Thereā€™s some people who have just been doing this for so long, they are very familiar with ā€œOh, youā€™re seeing this problem, and it has these symptoms? Oh, itā€™s likely due to XYZ.ā€ And they donā€™t know your system at all.

Right. Theyā€™re like ā€œItā€™s DNS.ā€ And youā€™re like ā€œNo, itā€™s not DNS.ā€ And then 17 hours later, it was DNS.

Right. And then thereā€™s the people whoā€™ve been there so long, theyā€™re familiar with all the problems. Theyā€™re like ā€œOh, when this thing happens, itā€™s because this API system and this thing, or this thing are down.ā€ Like, theyā€™re very familiar with the specifics of that. And to that, I would say that ā€“ when youā€™ve been there long enough that you know all the things that could go wrong, maybe we should be putting more resilience in strengthening that part of the code, if itā€™s so problematic that everyone knows ā€œWhen this thing happens, itā€™s this problem.ā€

But for me, the debugging is ā€“ I think Eric kind of mentioned this earlierā€¦ Itā€™s really your best way of reducing that time to solving a problem, is ā€œWhatā€™s your observability stack?ā€ Because I donā€™t feel like teams invest in that enough often; itā€™s always an afterthought, absorbability, both from just analytics metrics, things like Sentryā€¦ All kinds of just ways to kind of log out your application state, and getting a baseline; the sooner you have all that stuff in, you have a baseline of ā€œnormalā€, and itā€™s easier to kind of see when things are going haywire. You can set thresholds, you can monitor for changes etc.

So I would say really donā€™t sleep on observability. Itā€™s very much like the public health versus kind of ER; like, proactive versus reactive. But it usually really goes a very long way into kind of reducing how long it takes you to figure out whatā€™s going wrong. Itā€™s an important part of the debuggerā€™s toolkit.

I want to take something that Jerod said and extend it. So Jerod, you talked about changing one thing at a time, and I think that is an example of something that Iā€™ve found to be very important with debugging, which is just being extremely systematic about understanding what is true and what is not true. Iā€™ve found with a lot of newer engineers, or people who struggle with debugging, theyā€™ll jump to conclusions about whatā€™s probably going on, and then spend their time trying to verify that conclusion. And it comes back to - itā€™s hard to prove something is true, itā€™s much easier to prove something is not true. And so I always start with, ā€œOkay, what is going on? Show me the situation.ā€

ā€œWhat is going on?ā€ Yeah, thatā€™s what Eric said earlier. Yeah, ā€œShow it to me.ā€

[45:59] What do we know is true? What do we know is true? Can we confirm that? So going back to if weā€™re using logs, or weā€™re using a debugger, or whateverā€¦ If you know the error is happening in a particular function, donā€™t jump to somewhere down in the function and try to figure it out. Logout what is true when you enter that function. What arguments were passed? Do those match your expectations, or is there something unexpected happening on there? Start from validating those very basic, fundamental assumptions, because usually, bugs donā€™t arise because our assumptions were correct and then we implemented it wrong. Usually, they arise because there was a gap in our assumptions; we were assuming that something would be true, that it turns out in some situations is not true.

And so the sooner that you can get to the point of ā€œOh, hereā€™s the place where my assumptions are not being validatedā€, the sooner youā€™re going to be able to figure out, ā€œOkay, why? And is the problem that I need to handle this other case, or is the problem that something upstream is breaking and sending me invalid things?ā€ It gets you arrowed into that much quicker. But I think a lot of folks start with, ā€œOh, I think the problemā€™s hereā€, and they jump right in, and they never take the time to validate their assumptions and move systematically.

Brilliant. It reminds me just how little we do as kind of like engineers to test for like the non-happy paths; those assumptions are baked into so much code. I mean, you can look at failure statesā€¦ And itā€™s actually one of the beautiful things about being in the frontend space as a web developer, is that thatā€™s a portable skill, of being able to work in the browser. You hand me a URL if somethingā€™s going wrong, and Iā€™m going to be able to look at these really rich tools that you donā€™t get when you console.log in Node. I can actually expand out variables, and copy to the console, like you mentioned. Itā€™s almost always like at the network layer, where we see that some happy path assumption isnā€™t true anymore. And then thatā€™s whenever all the problems arise.

Iā€™ll give one other bit of generic adviceā€¦ This maybe more along the ā€œWhile Iā€™m coding, troubleshooting, debuggingā€, less so than just ā€œHere comes a production ticket.ā€ In my experience, itā€™s almost always your code. And this is just a humbling ā€“ I mean, 9 times out of 10. I mean, sure, the further you get away from your code, the least likely it is to be where the problem lies. The fact ā€“ like, is it in the Linux kernel? Probably not. Is it in Node.js? Probably not. Now, there are bugs there, there are problems, and there are things that change out from under youā€¦ But thatā€™s like the 1 in 10 cases, like ā€œWell, Nodeā€™s API has a bug in this version.ā€ And most of the time, 9 times out of 10, if youā€™re looking for the problem, look in your code, and then look in the code thatā€™s touching your code, and then work your way down. Because I, especially as a young man, would immediately ā€“ I was a Ruby on Rails developer, and I would dive into the Rails codebase immediately, and be like ā€œWhat are they doing wrong this time?!ā€ And it was always me. I was like ā€œWait a secondā€¦ā€ Talk about checking your assumptions, right?

So just be humble enough to start with your own code, and stay there for a while, even when you canā€™t find it, before you decide ā€œIā€™m gonna hop into Chrome Dev Tools and open up the source code for the dev tools. Maybe the dev tools are actually printing this wrongā€¦ā€ Thatā€™s how strongly I would not let myself be the source of the bugā€¦ So itā€™s almost always your fault.

Almost always.

Yeahā€¦

Butā€¦

Butā€¦?!

Well, it is almost always true, and you are absolutely correct, thatā€™s where you should start. And we did an episode where we shared debugging horror stories, and I will say the horror stories usually have to do with something in the environment.

Yeah. Thatā€™s why I said nine out 9 times out of 10. I mean, if you do enough bugs - I mean, 1 out of 10 is a decent clip. If youā€™re gonna do 100 bugs a month, itā€™s gonna be somebody elseā€™s fault. And thatā€™s a made-up number, of course, but itā€™s almost always yours.

Everything was working, until you put your code in. And then now itā€™s broken, soā€¦ Yeah, that is the one variable, is yourself.

[50:01] Yeah. Itā€™s also the thing that you can control the bestā€¦ Upstream bugs are the worst, because now youā€™re like opening a ticket, it goes into a queueā€¦ Hopefully, you have a workaround that you can do for now, and then you put a little note in there, like ā€œOnce this issue gets closed, I can take out this monkey patchā€, or whatever. And then that lives for like seven years in the codebase, of courseā€¦ But the further away the bug is from your code, actually the less agency and autonomy you have. And so itā€™s better than it is your own, because you can just change your own code. Whereas upstream - youā€™ve got bigger problems. But they do happen.

Have you used patch-package for issues like that?

No, please explain.

I see Kball is nodding over thereā€¦ I discovered it a few years ago, but effectively, you find an issue in some upstream package, something in your Node modules, you try your code, your code is flawless, as usual, and so you trace up, and then you find itā€™s some sort of Node moduleā€¦ And you go in there and you change the code for the Node module, and you fix it. So what this patch-package does is itā€™ll do a diff of your Node module, create a diff of that, generate a PR for the upstream package that has the issueā€¦ Meanwhile, anytime you install that dependency again for anyone else on your team, a patch will be applied to it, a Git patch will be applied to itā€¦ So that way, your fix for it before it lands upstream is at least in your project, and you can benefit from it. It works pretty well in my experience, with the exception of the more transpilation npm projects have, where they have like one single index.js file thatā€™s giant, it makes the utility a little bit lower.

Yeah, itā€™s really useful. It works best also with projects that are likely to accept your patch sooner, because the more thereā€™s churn ā€“ like, if you update the package, you need to now update your patch in patch-package, because otherwise it wonā€™t necessarily apply cleanly if thereā€™s been other changed aroundā€¦ So if you have a package that changes frequently, but doesnā€™t accept your change, it either youā€™re pinning to the version that you have, or youā€™re having to continually keep redoing that work.

Yeah, I donā€™t see how it would work without pinning a versionā€¦ Because if you canā€™t guarantee that your merge is gonna get accepted, youā€™re risking it just randomly breaking for others. But thatā€™s so cool, Eric; thanks for sharing that.

Yeah, Iā€™ll link that one up in the show notes.

Yeah. I mean, open source code is battle-tested, thereā€™s more people using it, so to Jerodā€™s point - yeah, start with your code first, because itā€™s likely the least ā€“ especially if itā€™s new, the least battle-tested code in your stackā€¦ But I mean, considering that only one out of every ten lines is code that you write in your application, for every 10 lines that you ship, 9 of those are from third party librariesā€¦ I mean, itā€™s pretty amazing that we donā€™t have more issues.

Itā€™s a large surface area.

ā€¦more issues around the integration layer.

It is. Sometimes Iā€™m still amazed at all it works.

Itā€™s really amazing. And not only that, just with security issues too, that thereā€™s not more burning security issues every time. Thatā€™s also very impressive.

Alright, do we have any final thoughts on debugging, tools you like etc. before we call this a conversation?

I want to look into Replay. Iā€™ve seen a lot of discussion about it. Replay.io. And the biggest question I kind of have is like when a bug has already happened, how can I get to that replay? Does it require like a Chrome extension, does it require an app to be running? What does this mean for like an end user versus as a developer tool? And I donā€™t have the answers. I donā€™t know if anyone else is has used itā€¦ But the promise of something that can give me a replayable session is - thatā€™s where I want to be, like developer experienceā€¦ I want to do my job normally, let the bugs normally happen like they do, and then try to just go back in time and be like ā€œOkay, now letā€™s pretend the code was actually this, and I did it right the first time around. Now does it play through cleanly?ā€ Thatā€™s where I would like to be in a developer world, of not have to have that stop because of an error and that cold start problem again.

[54:18] Right. Yeah, if reproducibility is the biggest time-sink for us, and like the one that you have to work through, if you can provide that, you can reduce the time to reproducibility, and provide an option to like just replay history with this code, versus the code that currently existsā€¦ I mean, youā€™re gonna save a lot of people a lot of time. And so thatā€™s great. I hadnā€™t seen this before.

Yeah. Do you want to just give people context or what Replay is, Eric, and if itā€™s available outside of the React world, orā€¦?

I unfortunately donā€™t. Itā€™s one of those tools to where youā€™ve got to invest the time into researching it. But itā€™s only been ephemeral, of like ā€“ I brought up the Tim Neutkens quote earlier, and it just struck a chord with meā€¦ Like, yes, super-complicated bug that would have been days to reproduce - I spent some time over at AWS, and every customerā€™s environment is different. And because of that, the way one thing behaved would be entirely different from something else because of some statefulness of their specific backendā€¦ And itā€™s like ā€œIf only I could see exactly how their backend was configured, Iā€™d be able to figure this out.ā€

So I think thatā€™s kind of like the thing, is that having ā€“ like, Kball mentioned, where Iā€™m at now is similar to where we used production data, with like a low ā€“ and thatā€™s been fantastic. So if that were extended even further, it would introduce time and recording into production, like real data with local files, that would be my sweet spot for just day to day work. And naturally, part of that is like debugging.

Yā€™all remember back in the day when Redux first came out, I think the biggest kind of a-ha was the time travel debugging feature? And I heard this straight from the maintainersā€¦ Itā€™s funny, actually, Mark Erikson, as well as Brian Vaughn from the React team, and Mark Erikson, both friends of mine now work at Replay, the startup that youā€™re talking aboutā€¦ But Mark is one of the maintainers for Redux, and he mentioned that surprisingly, not that many people took advantage of time travel debugging, despite it being the thing that people were most excited about, because it gave that predictability of like your state and being able to replay it. So yeah, Iā€™m curious to see if ā€“ I think maybe Replayā€¦

Did he say why that was the case? Maybe it was too hard to do, orā€¦?

I think config, setupā€¦ The pipeline around kind of, okay, once you capture the replay, how can you see it? I think Replay, the startup, is actually kind of smoothing that experience out.

Right. Thatā€™s what theyā€™re trying to do.

Yeah. So if they make it a service, Iā€™m excited to see if thereā€™s more adoption around it.

Yeah, because a mixed app with that has more than Redux wouldnā€™t get to benefit from time-travel debugging; only the state from the Redux store.

Right.

I think thatā€™s kind of the problem, is that itā€™s kinda like betting on the web and betting on the environment weā€™re in; all the statefulness that really matters is there in the browser, is there when youā€™re doing that console.log or your debug. So if the statefulness is managed there, thatā€™s the ideal, irrespective of how my app looks today in Redux, versus MobX, versus Prisma, or whatever else the next iteration is.

Well, and this is pointing towards something that might be worth touching on, which is writing code that is debuggable. And one of the biggest sources of challenge, as weā€™ve highlighted, is reproducibility. Reproducibility has to do with state. You have to get this thing, whatever it is, into the state that reproduces the bug. The more that you can separate state from functionality and implementation, and have your state encapsulated, and then have your functions encapsulated - and this is pointing towards functional styles of development, this is pointing towards declarative development, which was a direction weā€™ve kind of moved in for a lot of web frontend stuff at leastā€¦

[58:08] But the more you could separate those things out, so that you can test your logic independent of your state, and pass in all sorts of different states, and the more that you have state in a place that itā€™s easy to snapshot it and replay, or do things like that, the more debuggable your code is going to be, and the easier all of this is going to be.

Well said. Alright, we are hitting up against our time hereā€¦ Eric, thanks so much for coming on the pod today. Weā€™d love to have you back anytime. You donā€™t need to wait for Amal, or another debate episodeā€¦ Just give us a holler if youā€™ve got something to talk about. Weā€™d love to have you on the show more often. Where can people connect with you? Where can they get to know you, talk to you etc. on the internets, besides going to Texas and finding your house? I mean, that would be weird.

Just over barbecue, or somethingā€¦ Yeah, Iā€™m still on the Twitters, @EricClemmons, so just my full name. Otherwise, the GitHub, andā€¦ But yeah, Twitter is the best place to ping me.

Sounds good. Amal, Kball, thanks for debating with us as masterfully as you always do.

I donā€™t like debates, but this was fun. I donā€™t do well with time pressureā€¦

Hey, I meanā€¦ On this debate we won, you won, the listener wonā€¦ We all win. It does get any better than that. Maybe because itā€™s Friday, weā€™re recording on a Friday and Iā€™m just feeling gracious today. Iā€™m just allowing others to finally get in on the good, good wins that I usually rack up. The only person who lost today, letā€™s be honest - it was Nick Nisi. Because a) he didnā€™t win the debate, and then b) we barely mentioned [His beloved TypeScript]. Soā€¦ Thatā€™s two losses for Nick, which is a good note to end on.

Iā€™m Jerod, this is JS Party, on behalf of Amal, Kball and our guest, Eric Clemmons, thanks for listening. Weā€™ll be back next week with an awesome episode, Iā€™m sure. So stick around, and weā€™ll talk to you all on the next one.

Changelog

Our transcripts are open source on GitHub. Improvements are welcome. šŸ’š

Player art
  0:00 / 0:00