Description Transcript
Having trouble figuring out why your Retool apps aren’t behaving as expected, or looking to sharpen your debugging skills?
This webinar gives you a practical toolkit for breaking down issues across Apps and Workflows. We’ll walk through core debugging tips and tricks in Retool and show you how to apply them directly in your own builds.
You’ll learn how to isolate root causes, trace unexpected behaviour and steer clear of common pitfalls.
We’ll also look at how AI can speed things up — from explaining errors and spotting patterns to rewriting queries and guiding your next troubleshooting move.
Read more 0:03 Nice. So, let's get cracking. Um, thank 0:06 you so much for joining and and taking 0:07 your time to um participate in this 0:10 webinar. Uh, this is going to be on 0:12 debugging in RTO. Um, talking through AI 0:15 powered troubleshooting for your apps 0:17 and workflows. As an introduction from 0:19 me, I'm Ollie Clyde. Uh, I'm a support 0:21 engineer here at RETL. I have a 0:23 background in software development and 0:25 tech consulting. And unsurprisingly, in 0:27 my day-to-day work with customers, I do 0:30 loads of debugging, helping solve lots 0:32 of their more technical um challenges 0:34 and problems across retail. 0:37 So, let's start with a brief agenda of 0:40 what we're going to use this uh our 0:42 session for. Uh I'm first going to give 0:45 a little introduction around, you know, 0:46 what is debug debugging, why is it 0:48 important, etc., etc., you know, why are 0:50 we here? Um and then we're going to 0:52 spend the bulk of the session going 0:53 through uh the scenario that we're going 0:55 to use and then um spending around 354 0:59 minutes um talking through the scenario 1:01 and we'll give more details around 1:03 instructions um and how you can take 1:05 part or just watch along um for this 1:07 example. And then finally, um, at the 1:10 end, we'll run a little recap talking 1:12 through what were the main points I was 1:14 trying to get across, um, as well as 1:16 hopefully some time, um, depending on 1:18 how fast we go for some questions and 1:20 answers at the end. Um, again, yeah, 1:22 feel free to kind of chuck any questions 1:24 as we go, um, in the chat. Um, but with 1:27 that said, let's get let's get started. 1:29 So, uh, the art of debugging. Um, 1:32 sometimes it feels like an art, 1:34 sometimes like a science. Um I first of 1:36 all wanted to start with kind of why is 1:38 it important you know you know why are 1:39 we here why is it worth um discussing um 1:42 and I think essentially software 1:44 development is just as much about 1:46 debugging as it is about building uh and 1:49 it's kind of such a crucial skill and 1:51 although retool as maybe you already 1:53 know it's makes it far easier to build 1:55 software um and reduces that barrier to 1:57 entry it still requires um some of those 2:00 fundamental software development skills 2:02 and debugging skills um and as quoted by 2:05 Brian Kernahan um who is a famous 2:08 computer scientist. Um he says that 2:10 debugging is twice as hard as writing 2:12 the code in the first place. Um I 2:14 imagine maybe there's been times in your 2:15 life there's been very few in mine but 2:17 I've written a piece of code or built 2:19 some piece of software and it's worked 2:21 first time and I think I'm a incredible 2:23 genius. Um but 99.9% of the times uh I 2:27 get something wrong or I haven't thought 2:29 of an edge case or whatever it may be 2:31 and I need to iterate and um improve 2:34 what I've already built. Um and so it's 2:36 it's really kind of a part and parcel of 2:38 building things um is debugging. Uh 2:42 following that I think it's also worth 2:44 framing this in the importance of 2:47 defining the problem uh before the 2:50 solution. Although we'll mainly talk 2:52 around specific techniques within rout 2:54 retool and some kind of common errors 2:56 that I come across, it is a real real 2:59 common pitfall to get hung up on solving 3:01 a specific problem rather than 3:03 understanding the broader picture. Um, 3:05 and a quote that I I like to keep in 3:06 mind particularly when working with 3:07 customers is if I had one hour to save 3:10 the world, I'd spend 55 minutes defining 3:12 the problem and only five minutes 3:13 finding the solution. Um, from Albert 3:15 Einstein. I think it's a really nice way 3:17 to ensure that we're we're not getting 3:21 stuck in the weeds and obsessed around a 3:23 technical solution, but actually 3:24 understanding kind of what are we 3:25 solving for. I also thought it's worth 3:29 kind of framing this in the in the 3:30 context of of AI um and kind of both 3:33 where retail's going with this um but 3:35 also the wider industry. Um and I think 3:37 you know has this changed this you know 3:39 is debugging as important? Um and I 3:42 think on that first point um I think 3:45 it's you could argue that it's now less 3:47 about understanding specific technical 3:49 concepts or techniques um and more about 3:51 working through problems logically. Um 3:54 and so if anything um obviously I'd be 3:57 biased from from my position and role 3:59 but I would argue that debugging if 4:00 anything is more important um than it 4:03 kind of ever used to be. So you're more 4:04 likely to encounter code bases or 4:06 software or retool apps where maybe you 4:09 don't actually understand how it was 4:10 built um or you know who wrote the code 4:12 or how why it was written in that way. 4:14 Um and actually so you're more likely to 4:16 need to quite quickly understand the 4:19 problem you're trying to solve the 4:20 context around it etc etc. Um and so if 4:22 anything some of those core skills 4:24 around logical thinking and problem 4:26 solving I think are just as important if 4:28 not more so now with AI taking away 4:30 maybe you know some of the technical 4:31 knowledge you may need. And then 4:34 finally, I think an easier point to make 4:36 on on the second around defining the 4:37 problem. Um, I think it's probably going 4:39 to be easier than ever to create 4:41 solutions and build software. You know, 4:43 as I mentioned before, the barrier to 4:45 entry in software development is is 4:47 lowering and and that's particularly as 4:49 we'll talk about with assist, which is 4:51 retools um solution to use natural 4:54 language to build applications. There's 4:56 a greater chance that you're going to 4:57 build solutions that potentially don't 4:58 pro solve real problems. Um, and so I 5:02 think again that that makes this quote 5:04 an area even more important to think 5:05 about. Um, and so we'll touch on this 5:07 again kind of throughout this um, 5:09 webinar, but I think it's an important 5:10 thing to kind of anchor um, as we as we 5:13 go through um, this scenario. And so 5:16 moving on to that, um the scenario for 5:19 today is going to be about our colleague 5:22 Jerry who has built an MVP for a 5:24 software access request portal to help 5:27 demo where the retail can be used to 5:28 manage our company's various software 5:30 providers. Um but he's left for holiday 5:32 in Hawaii before finishing it, leaving 5:34 us to pick up the pieces. Um I think 5:36 it's fair to say we're not a fan of 5:38 Jerry anymore. He's really left us in 5:39 the lurch here. But unsurprisingly, it's 5:42 given us some good sections to run 5:44 through around debugging um and retool. 5:48 So, we're going to have these five main 5:49 sections that we're going to touch on. 5:51 We're going to start with app context 5:52 and the debugging tools. Then, we're 5:54 going to go into root cause analysis. 5:56 So, trying to understand the source of 5:59 of bugs and issues uh within RTO. We're 6:02 then going to get into resource query 6:03 debugging, JavaScript debugging, and 6:05 finish on workflow um debugging. Um to 6:11 um set some context around u kind of 6:13 knowledge for this. Um if you've never 6:16 touched retool, that's perfect. We'll go 6:17 really slowly and you can pick up um 6:20 lots of the basic things around 6:21 debugging within retool. If you have 6:23 used retail before and you're still 6:24 looking to try and find some new 6:26 techniques or new areas you come across, 6:27 I do hope that I will also um provide 6:30 some additional tools or or things you 6:32 haven't learned before. Um so hopefully 6:35 we can we can cover kind of both um kind 6:37 of both scenarios there. So onto some 6:41 logistics. You should have received an 6:43 invite email from our webinar instance. 6:46 It's AMIA um gosh actually what is it 6:50 called? It is called air amir 6:52 agents.retool.com. 6:54 Um, and using that invite email, you 6:56 should be able to log in and create an 6:58 account. Um, if you've joined us before 7:01 also, I could see some had logged in 7:03 earlier. You may need to kind of log in 7:04 again. And that should then take you to 7:06 this instance. Um, and this is if you 7:08 want to follow along um, manually, you 7:11 know, practically with us, you can uh 7:14 set up a copy of an app to then run 7:16 through the scenario with me. or if 7:18 you're not so interested, you can just 7:19 watch along and um watch me do it. Um as 7:23 also that's posted in the chat by Amar, 7:25 we should also have some instructions 7:26 for you to run through as well um if you 7:29 kind of get lost or um want to catch up 7:32 with where we are, but also have a 7:33 written summary of kind of what we 7:34 discussed today. So the main thing to 7:38 set your own app up is to ensure that 7:40 you copy um the main app. So it should 7:44 be once you log in you should be taken 7:46 to recents potent. Hopefully you should 7:48 see it there but if not you may need to 7:49 move to published and search for it. Um 7:52 and you can search for debugging or 7:54 main. 7:56 Um and in doing so you should then be 7:59 able to this ellipses at the side of the 8:02 app. Um you should then be able to 8:04 create a duplicate. 8:06 you'd want to include your email within 8:09 the duplicate just to ensure that um uh 8:11 there's you know there's no copies. If 8:13 you use the same name as someone else, 8:14 it will cause an error. Um and you want 8:16 to hopefully when you create it, you 8:18 should be able to set it um it in by 8:21 default it will set it within your own 8:22 drafts. Um so for example here if I do 8:25 olide at retool.com 8:29 and create the app 8:31 and it should be within my drafts here. 8:33 Um, and so then within those drafts 8:36 folder again at the top, you can then 8:37 click onto the app to then start this 8:39 web webinar scenario with me. Um, I'm 8:43 going to give a little pause there as I 8:44 imagine there may be some questions or 8:46 you're still logging in etc etc and 8:48 maybe I can give another run through um 8:50 if needed. 9:07 Nice. So, hopefully you're sat there 9:08 with your with your drafts tab open and 9:11 a nice copy of the main app. Um, and 9:14 then you can then click through onto the 9:16 app, which will then initially take you 9:17 to the preview. Um, I'm also taking the 9:20 fact that Omar hasn't um shouted at me 9:23 that there aren't any kind of core 9:25 questions or problems so far. So, I'm 9:27 going to take that as a sign to get 9:28 stuck into the scenario. 9:32 So the preview of the app. Um let's just 9:34 take a moment to have a little view of 9:36 what we think is going on here. So I can 9:38 see we have unsurprisingly this software 9:41 access request portal. Um at the top 9:44 there seems to be some KPIs around total 9:47 requests, pending approvals um and 9:49 approved requests. Then seems to have a 9:52 main table which I assume are just my 9:54 software access requests. Um that now 9:58 seems to be empty. And at the bottom 10:00 there seems to be a table for appro 10:02 admins to approve 10:05 um any access requests. It seems to be 10:07 at the top I can refresh but we seem to 10:10 be getting an error. And if I go to open 10:12 a request, okay, I can't seem to find 10:15 select any software. And so clearly 10:16 there's lots of issues here. Um so 10:18 chances are this is kind of some type of 10:21 portal where end users can come on uh 10:23 potentially request um software and 10:25 admins can then um either kind of reject 10:28 or approve that. So now let's go into 10:31 the bulk of uh the webinar which is 10:33 going to be editing and seeing what's 10:35 going under the hood. So at the top 10:37 right you should have the option to 10:38 click edit app and in doing so that will 10:42 then open up the app into this visual 10:44 editor. Um, and this is where we can now 10:47 look under the hood of what is going on 10:49 here. 10:53 So, where where do we start? Where's a 10:55 good place to get going here? Uh, and 10:57 with this newer feature in assist, which 11:00 can be found at the left sidebar at the 11:02 bottom, there should be a little icon 11:04 that you can click on to with assist. 11:06 This is a great place to start to ask 11:10 what does this app do and how is it 11:11 structured. Um, so with assist at the 11:14 bottom, we can select different modes. 11:15 So whether we want to build, create an 11:16 edit or just to ask. So for now, let's 11:20 just ask how does this app work and what 11:24 does it do? 11:26 And hopefully that should give us a nice 11:28 rundown uh of what's going on here, but 11:30 also while this is loading, I'm also 11:33 going to point to some core areas that I 11:36 would always go to when first coming 11:37 across a new app. Um on the sidebar we 11:40 have a load load of useful tools that um 11:42 you're going to come across or when 11:43 building and retool use frequently. The 11:45 first one at the top is pages. So this 11:47 gives a nice overview of if it's a 11:49 multi-page app, what are the page 11:50 structure here? At the moment it's just 11:52 one page. So it's nice and simple. We 11:54 also have the component tree. So this 11:55 gives a nice breakdown of how the 11:58 component structured. Are there any 11:59 hidden components? Um how do they fit 12:01 together? Not so important for today's 12:03 webinar but something to um keep in mind 12:05 and be aware of. And then importantly 12:08 the main section you should have is um 12:10 the code area. So this should give a 12:12 breakdown of quite simply all of the 12:14 logic um that's uh your app is 12:16 functioning on. So such things such you 12:19 know all of your queries, some variables 12:21 um some transformers etc etc. We're 12:24 going to go into this area in a lot more 12:26 detail and some of the kind of core bits 12:28 of this app within it. Hopefully if we 12:30 go back to exist we should now have a 12:32 nice overview of what's going on here. 12:35 So it seemed to have a clear purpose. So 12:37 the app allows employees to request 12:38 access to different software 12:39 applications and enables administrators 12:42 to review and approve and reject those. 12:43 So pretty much exactly what we thought 12:45 when we first had a little overview. Um 12:48 that seems to have that request button 12:49 at the top right where they can have a a 12:51 modal to then submit a request. Um we 12:55 using a retail database to be able to 12:57 store those requests. We have some 12:59 metrics at the top. We have the requests 13:02 table etc etc. and then the approval 13:05 model at the bottom. So when an admin 13:06 clicks to review a request, they can 13:08 approve it and reject it. Now some 13:10 technical architecture which is a really 13:12 useful bit of information to understand 13:14 kind of what's some of the logic that's 13:15 going on here. So we seem to have retal 13:18 database with a mock access requests 13:20 table as well as a postman mock server. 13:23 Um, and so 13:25 they seem to be giving our main uh 13:27 sources of data for this application as 13:29 well as a whole selection of different 13:31 queries um that's pulling or inserting 13:33 data um as well as some transformers um 13:36 that we're going to get into in more 13:37 detail. 13:39 Brilliant. So that's now given us a nice 13:41 overview of what's going on here. I'm 13:43 going to close that for now. And now the 13:45 other area I want to mention is the 13:47 debugging tools. So, at the bottom right 13:50 here, you should have the option to be 13:51 able to open up the debug tools. Um, and 13:54 if you haven't come across these before, 13:56 unsurprisingly, we're going to use these 13:57 very heavily during this session. 14:00 And I'm going to give a little just 14:01 overview of of how they're structured 14:03 and and uh how you can use them. 14:08 So, pardon me. So, it may look familiar 14:10 to some of you um because they mirror 14:13 the dev tools or similar debugging tools 14:16 um on your browser. Um just for those 14:18 that are curious um I always think it's 14:20 kind of um quite interesting to see um 14:22 if you double click on a page um kind of 14:25 outside of the retail visual editor um 14:27 you can see your own browsers dev tools 14:29 and unsurprisingly here you can see both 14:32 the kind of structure of this page lots 14:33 of the code as well as also uh the 14:36 console as well and network requests etc 14:38 etc um and so we've created our own 14:41 retool specific debugging tools that can 14:43 give you lots of information around um 14:45 what's going on in your retool runtime 14:47 time. And so the first page is the 14:49 console. So this will give you an 14:51 overview of all of the successful 14:53 queries, any errors, and also any info 14:55 messages. So for now, we're going to 14:57 filter it. So we just see the errors and 14:59 we just see the info messages. And this 15:02 is the the the main intel that we can 15:04 use to um start debugging. The other 15:07 area I wanted to highlight is the 15:08 timeline. So this gives a visual 15:11 representation of the query execution 15:13 order. So typically all of the queries 15:14 that are fetching or updating data um 15:18 and you can see um information around 15:21 timing of these etc etc. We're not going 15:23 to go into much detail on this now. This 15:25 is mostly mostly useful but for 15:27 performance issues um and the like. 15:31 Uh and the other area is state. So this 15:34 gives you a view of all of the current 15:35 components, queries, variables um etc 15:38 etc that are available um within retool. 15:41 Um what is state? state is effectively 15:44 the the snapshot at this given moment in 15:47 time um of you know all of the 15:49 information um within retool. We're 15:51 going to come into more detail around, 15:54 you know, why is state important, how 15:56 does it work, um, and how you can use it 15:58 to debug a little later on. Um, so it's 16:00 good to be able to flag this now. 16:03 Brilliant. So, I'm going to go back to 16:04 the console and have that nice kind of 16:07 open on the page here. Um, and now that 16:09 we've understood what's going on here 16:10 with the context of the application, as 16:12 well as had a little um, mooch around on 16:15 the console logs, we're now going to get 16:16 into the first kind of main section, 16:19 which is how do you find the root cause 16:20 of bugs? You've come across an 16:22 application and there's a load of errors 16:23 showing, oh no, you know, where do I 16:25 start with all of this? Um, and so we're 16:28 going to talk through kind of two main 16:29 ways to go about this. Um, and 16:32 effectively a great place to start 16:33 unsurprisingly is just to pick one of 16:35 these and use this to work your way 16:37 backwards to find the root cause of the 16:39 issue. Lots of times errors like this 16:42 are showing as symptoms of a issue 16:44 further upstream. And so we're going to 16:46 um we're going to work through a 16:48 scenario together. So to be able to open 16:50 up um and investigate this error in more 16:53 detail, you should be able to click um 16:56 on these on the side here to open up the 16:58 associated query with this error. The 17:01 one that I want to open up um is the one 17:03 that is named all requests with software 17:06 name. So you can see that on the right 17:07 here. For me, it may be different for 17:09 you. It's the fourth one down. And if I 17:11 click onto that, that should then open 17:13 up this transformer for me. And so then 17:16 I can use both the error in conjunction 17:18 here and also uh the transformer open to 17:21 now start debugging um um and finding 17:24 the root cause here. So for those that 17:25 aren't aware, transformers, you know, 17:27 what are they? um effectively they're 17:29 ways that um they're code within retool 17:32 that you can use to write larger re 17:34 reusable blocks of JavaScript. Um and 17:36 unsurprisingly it's typically used to 17:39 transform data. So whether you're 17:41 combining data sets, filtering or or 17:43 kind of whatever it may be so if we have 17:46 a quick run through together of what we 17:47 think is going on here at the top we 17:49 seem to be pulling in uh lots of kind of 17:52 all of the access requests. Then we seem 17:54 to be also getting the software 17:56 providers. Um, and then we seem to have 17:58 a function that is simply combining the 18:00 two. So we've got all of the quest 18:02 requests and we're going to find for 18:03 each request find the associated soft 18:05 piece of software and then we're going 18:07 to match on that and then we're going to 18:09 try and find the uh name of the 18:11 software. Um, and then we're returning 18:13 that so that they're kind of combined 18:15 together. So with that in mind, let's 18:17 get started into kind of analyzing this 18:19 error in more detail. So, as I mentioned 18:22 before, great place to start is actually 18:24 on the error itself. Unsurprisingly, um, 18:26 one thing to note, something that I do 18:28 all the time is I skim read an error and 18:30 then I think, oh, I know what's causing 18:32 this. This is simple. What am I, you 18:33 know, obvious don't take the time to 18:35 actually properly read it and analyze it 18:37 and then, you know, I'm down a rabbit 18:39 hole um when actually if I'd taken the 18:40 time initially, I could have saved 18:42 myself um lots of effort. So, let's take 18:45 a moment to read through this error. 18:47 We've got one error. Software.find is 18:49 not a function. And by clicking onto the 18:51 error, typically in JavaScript, you'll 18:53 always find a bit more information 18:54 around which line it's on. And so we can 18:56 see here it's highlighting line five. So 18:58 if we go to line five in the 19:00 transformer, we can see that 19:02 software.find function. 19:07 Now software defined is not a function 19:10 typically means that the property of 19:14 fine on software um doesn't exist. And 19:17 so in a slightly obscure JavaScript way, 19:19 simply that this is saying software is 19:21 most likely undefined 19:23 um or or kind of not appropriate an 19:25 array to be able to call.find on. Um so 19:28 let's now work our way backwards from 19:30 this using um the first method that is a 19:33 really powerful tool within a retool. Um 19:35 which is being able to hover over any 19:37 piece any variable um within a piece of 19:40 JavaScript within retool to understand 19:42 its current state. So if we were to 19:44 hover over software here we can quickly 19:45 analyze okay well you know it is 19:48 software indefined is it an error and in 19:50 quickly doing so here I can analyze the 19:53 data and I can see yeah there's there's 19:55 a clear error going on here and an error 19:57 message bad request etc etc so that is 20:00 undoubtedly must be causing this 20:02 software.find defined error in the 20:04 console. Um, and if we take a moment to 20:06 work our way back from there, we can see 20:07 software is defined at the top and then 20:10 it's actually defined from this query 20:11 get software providers. Um, as you may 20:14 know in RETL, a kind of real trademark 20:16 retool thing. Double curly braces allows 20:18 you to access any of these components 20:20 queries um state within RET um and and 20:23 kind of yeah access and then use that 20:25 data. Um, and so we can see here again 20:27 hovering over it, it's coming from this 20:30 get software providers query. Um and so 20:33 if we were to hover over the select icon 20:35 at the top, we can then open up the uh 20:37 culprit here. So that's one method which 20:40 is using uh basically the inbuilt um 20:44 function to hover over a v variable and 20:46 view the state instantly. Um it's really 20:48 powerful, really easy way to quickly 20:50 understand what's going on within a 20:52 within a transformer. 20:54 But the other method that I wanted to 20:55 also talk through is um how you can use 20:58 state and understand understand state to 21:00 debug more complex issues. Um so if I 21:04 now go back to opening the transformer 21:07 and I now open up the state tab um I'm 21:10 going to give a little uh little 21:12 overview story time of why state is 21:15 important and how you can use it to 21:16 debug within retool. So for more complex 21:20 issues typically where maybe unlike here 21:24 where we've got a clear error where 21:25 maybe data isn't showing where you think 21:27 it should be or a component is not 21:30 getting the correct column or or 21:31 whatever it can be a lot harder to 21:33 actually understand particularly more 21:35 complex applications where the data is 21:37 coming from and what links into what. Um 21:40 and so this state tab is a great place 21:42 to be and so why is it important and and 21:44 and kind of why is it a concept that we 21:46 need to understand? Um, and so to give a 21:48 brief overview, essentially front-end 21:50 frameworks like React or Angular, maybe 21:52 you've heard them heard of them or 21:54 worked with them before. Um, 21:55 essentially, 21:57 you know, why do they use state and why 21:58 is dependency so important? And it's 22:00 because if we didn't track states and 22:02 the dependencies between them, um then 22:05 essentially anytime a piece of software 22:07 updated in your in your app, you clicked 22:09 button um or sent a request or whatever 22:13 it may be, we would need to rerender the 22:15 whole page in order to ensure you know 22:17 all the all the right bits of 22:18 information updated in in your um user 22:21 interface. Um and so that unsurprisingly 22:23 that's deeply inefficient. Um and so 22:25 like those frameworks here, that's 22:27 exactly what we're doing in retool. 22:28 We're analyzing you know for each uh 22:30 piece of state you know what is it 22:32 dependent on and if you see here at the 22:34 bottom uh if we search for all requests 22:39 with software name so if we're searching 22:41 for this transformer we can actually see 22:43 you know what it's updating and what it 22:45 depends on that's really powerful and 22:47 really useful um I imagine if you have 22:49 ever played around with any of these 22:51 front-end frameworks like React um there 22:53 will be a time where dependency loops 22:55 happen um or um 22:59 um or yeah you haven't quite configured 23:01 state correctly um using ustate and it 23:03 causes all sorts of issues whereas here 23:04 we have a visual representation to 23:06 actually understand okay so you know 23:07 what is it updating and what what does 23:09 it depend on and then this is then 23:11 really powerful to then move up and down 23:13 that chain to be able to find the root 23:14 cause of different bugs. So if we were 23:17 to go down the chain in this example, so 23:19 clicking through on the component, the 23:21 table that should be displaying this 23:22 data, unsurprisingly, it's not showing 23:24 any data because it's relying on this 23:26 transformer. So if we go back up the 23:28 chain, we can see the transformer here 23:30 and it's null. Unsurprisingly, we just 23:33 discussed that, you know, has currently 23:35 has an issue returning any any data. So 23:37 nothing here. But now if we go back up 23:39 the chain, just like we figured out 23:40 before, we can see get all requests 23:42 query. And unsurprisingly, we do have a 23:44 request here. This is the one that is 23:45 working. Uh again, if we go back back, 23:48 we can now go check get stuff with 23:50 providers. I know we've already figured 23:51 this one out, but unsurprisingly, yes, 23:53 this is showing as having the error. 23:56 So, I'm going to give a little um pause 23:58 there. So, just give a recap. So far, 24:00 we've discussed how to understand um app 24:02 context with assist um and the debugging 24:05 tools. And then we've discussed two of 24:07 the main methods to um find the root 24:09 cause of issues. um one by 24:12 uh using the kind of inbuilt ability to 24:15 hover over variables um within retool to 24:18 understand its state but also the 24:20 concept of the state tab in and retool 24:22 and the ability to move up and down the 24:24 dependency chain. 24:27 So with that said we want to now open 24:29 get software providers uh as we have um 24:31 quite extensively covered that this is 24:33 most likely the root cause of the issue 24:35 and we're now going to get into resource 24:37 query debugging. So with any um uh kind 24:41 of query in the code editor um you can 24:43 both either test or run the query. Uh 24:46 main difference being test you're just 24:47 running it within the context of this 24:49 output you know output pane within this 24:51 query whereas run you're running it in 24:53 the context of the app. So you're 24:54 updating this the state um in the 24:56 context of of the application. Um so for 24:58 now we're just going to run test um to 25:00 not change anything and we can get a 25:02 clearer breakdown of the error here. 25:04 Invalid credentials error unable to 25:06 authenticate. double check your API key 25:08 and try again. Now, this is a classic um 25:11 authentication error. Again, probably 25:13 one of the most common um kind of 25:16 resource errors you're going to come 25:17 across. So, we're going to walk through, 25:20 you know, what are the main scenarios 25:21 here and how how can you go about 25:22 debugging this. So, typically with 25:24 authentication errors, there's um only a 25:27 limited number of options that could be 25:28 causing this. So either we aren't 25:30 sending the API key, we're sending it, 25:32 but it has the wrong credentials, or 25:34 we're sending it in the wrong format for 25:35 this server uh to be able to um uh 25:39 interpret it. So let's work our way 25:41 through kind of understanding what which 25:43 of those three is it likely to be before 25:44 we go into depth of actually researching 25:47 um uh the solution in more detail. So in 25:51 the output pane, we can uh switch across 25:54 to API request. And this gives us a nice 25:56 little breakdown of both what we're 25:58 sending. So the request so what what 26:00 we're sending to the resource uh and the 26:02 response of what are we what are we 26:03 getting back? And if I go to the request 26:06 property here um I can view okay we are 26:09 sending an API key. Um and it's nicely 26:11 sanitized by retool. Um so we do seem to 26:14 be sending something here. So next I'm 26:16 now going to check okay you know it does 26:18 seem to be the correct API key. Uh and 26:20 like I was showing before the ability to 26:22 hover over variables. We can hover over 26:24 this one and we can view. Okay. Yeah, we 26:26 are sending an API key here. Just as a 26:29 disclaimer, it's generally not best 26:31 practice to store an API key um kind of 26:34 in the header within the resource query 26:36 in an app. It's better unsurprisingly to 26:38 have it within the resource itself, but 26:40 for demonstration purposes here um I've 26:42 I've set this up um kind of within the 26:45 query. So, we've ticked off those first 26:47 two. So, chances are it's actually 26:48 something in how we have configured the 26:50 header. So we're going to go about um 26:52 asking assist to see whether it can help 26:54 us with this. So with opening up the 26:57 assist panel on the side uh we have the 27:00 ability to reference things within 27:02 within the app. So if I uh type at I can 27:07 then search for get software 27:10 uh providers. So I am selecting this 27:14 specific query and let's ask and see if 27:16 assist can help me. 27:19 How should I be setting up the resource 27:24 uh API key here? 27:28 So great class great place to start is 27:31 um asking assist or AI in general you 27:34 know how should I be configuring these 27:36 resources um how do they work you know 27:38 you know I'm getting this error back 27:40 typically you know what does it mean and 27:42 while assist is working on a little 27:44 response there and it seems to actually 27:45 have 27:47 given it um and we'll see if it 27:57 So it seems to be struggling here to get 28:00 understand what's going on. So it's 28:01 saying how to set up the API key. You 28:02 have two options. Create and configure. 28:08 So I don't think it's quite getting to 28:10 the root cause here. So the other option 28:12 is if AI maybe isn't quite giving you 28:14 the solution. Um the other option is 28:16 actually to go the old school way which 28:18 is going finding some documentation. So 28:19 let's search for Postman mock server um 28:23 API key and let's try and research. 28:26 Okay, how should things be configured 28:27 here? Uh I'm not going to read through 28:29 the docs with you um on this call but 28:31 let's have a quick uh run through and we 28:34 can see when creating a mock server from 28:36 an API call and if we give a quick skim 28:39 down here we can see okay to the request 28:42 X API key header. So actually it seems 28:44 to be we we're probably sending the 28:46 header in the wrong format. So if we go 28:48 back. Yeah, we're sending API key, not X 28:51 API key. Let's change it to X API key. 28:55 Hopefully give that a test. Amazing. 28:58 That's now returning a list of software. 29:00 So let's now click save and run. 29:03 Wonderful. That is working and sending 29:05 the right request. One. Amazing. 29:08 So to give a brief recap, we've 29:10 understood the app context. we have gone 29:12 into root cause analysis and then we 29:14 have looked at using both assist and 29:16 also manually looking at the 29:18 documentation to try and understand um 29:21 how a resource should be configured and 29:23 we've changed the resource header here 29:24 to X API key uh which is the header that 29:28 this postman server is looking for and 29:30 so now we're getting the appropriate 29:31 list of software providers I assume here 29:34 that um for this demo for this MVP that 29:36 Jerry's made um we're just currently 29:38 using example list of of software 29:44 Nice. 29:47 I'm going to take a quick pause there, 29:48 have a have a little drink, 29:51 and then let's go on to the next 29:54 section. 29:57 So, now we've made this change, we've 30:00 made this fix, let's see if there's more 30:01 errors for us to um get stuck into. So, 30:05 you can either reset the app state from 30:07 the top right here. You can click on the 30:09 ellipses 30:11 uh on you know at the top right of the 30:13 editor and click reset app state. Um or 30:15 you can just refresh the page and this 30:17 will just reset the state to see okay um 30:20 let's let's see if there we're still 30:21 getting any issues. Uh and just like we 30:23 did before let's go straight to the 30:25 debug tools to see if we have any 30:26 problems. 30:28 And looks like we're still got some 30:30 errors that are going on here. So just 30:32 like we did before let's start with 30:33 these and work our way backwards of of 30:36 what could be causing this. Um so again 30:38 like I did before you can open up 30:41 uh this specific uh route of this bug um 30:45 by clicking onto the um item here and 30:48 that will then open the transformer and 30:49 it seems to be the same transformer we 30:51 were looking at before. So the one that 30:52 was taking the requests getting the 30:54 software um and adding the software name 30:57 to the to the requests. And now let's 31:00 get into the wonderful world of 31:01 debugging in JavaScript. 31:04 So 31:07 it's a lifelong journey understanding 31:09 JavaScript errors and getting better at 31:11 debugging with it. Um I wanted to 31:13 highlight one of the main tools that u 31:17 that you would use to debug in 31:18 JavaScript um and then kind of talk 31:20 through um kind of some more areas from 31:23 that. So like we did before let's do a 31:26 slow work through of looking at the 31:28 error in more detail. So error cannot 31:30 read properties of undefined reading to 31:33 uppercase 31:35 and like we did before let's open up 31:37 this error and we can view which line 31:40 it's happening on. So this is line 8. 31:43 Let's go to line 8 in the transformer 31:46 and we can see um again here that two 31:49 uppercase issue. Um so similar to that 31:52 find.software issue the same thing here 31:54 means we're trying to read to uppercase 31:57 on full name. Um but 32:00 full name probably most likely is 32:02 undefined or doesn't exist here. Um so 32:04 let's now try and work our way back from 32:06 there. So looking at the code here, we 32:07 can see that there's a match um made on 32:10 software. Um so chances are here it's an 32:13 issue with um whether full name exists 32:16 as a property on software. So what we're 32:19 going to use here is something called um 32:21 console logs. Um, so effectively, 32:24 unsurprisingly, they're ways to be able 32:26 to print information into the console 32:28 that you have on the side here in your 32:30 debug tools. Uh, and they're one of the 32:32 main ways to understand um the 32:35 information that's what's going on 32:36 within um your logic. So you can do that 32:39 by typing console.log 32:42 and then you just type the specific 32:44 variable that you're looking to print. 32:45 And typically I always like to also 32:47 include a string, you know, a comma and 32:49 then a string to then also print, you 32:52 know, what am I actually showing here. 32:53 It can sometimes be hard if you have 32:55 lots of console logs to understand 32:57 what's printing what. I'm going to do 32:59 this for software and also while I'm 33:00 here, it can also just be useful to get 33:02 as much information as we can. So I'm 33:04 going to also do requests so we can see 33:07 both of them. And then we have the 33:09 ability to run a test. And then as you 33:13 can see here, it should then print out 33:15 in your console the information. You'll 33:17 need to make sure that you have both the 33:19 errors, well importantly the info 33:21 messages enabled. So you can view 33:23 console logs. And you can see every time 33:25 this piece of code runs, it's going to 33:27 keep printing out this information for 33:29 me. And then I can use this to 33:32 understand, okay, let's first look at 33:34 requests. And I can see requests is 33:36 coming through and nothing unusual 33:38 there. But if I open up software and 33:41 let's say we see we've got an array of 33:43 objects here. Um and if I open up the 33:45 object I can see the structure of the 33:47 software and we seem to have an ID a 33:49 name and a notes. So actually having a 33:51 look here we are defining the name um as 33:55 a property um rather than full name 33:57 here. So actually I think this should be 33:59 name rather than full name. So, I'm 34:02 going to change that. And like we did 34:03 before, I'm going to run a test. Ah, we 34:05 now have a software request with the 34:07 software name here. Amazing. And if I 34:10 run save, let's double check that. 34:11 Perfect. So, that's now saved and 34:12 working. We've got an access request 34:14 with a software name. So, that's working 34:17 as expected. 34:20 So, you may be thinking, that's great, 34:21 Ollie. I've used console logs, but that 34:23 was quite a lot of effort. And you just 34:25 showed me earlier around how you can 34:27 hover over um any variable in retool and 34:30 understand straight away what's going 34:31 on. So I could have just gone there. 34:33 Let's have a look at what the match is 34:34 made up of. We've got ID, name, and 34:36 notes. Okay, come on. That's name 34:38 straight away. Very quick fix. Um why 34:41 have you showed us console log here? Um 34:43 and I think the the main reason is um 34:45 for more complex applications um and 34:48 more complex pieces of code um 34:50 console.logs logs is always the fallback 34:52 to go to to understand the makeup of 34:54 what's going on here. Um, typically when 34:56 you find 34:58 uh AI can is incredibly efficient at 35:00 writing good bits of code. So if I was 35:02 to give this to um an AI and say write 35:06 me a more efficient solution, it 35:07 probably will come up with a better way 35:09 of writing this this piece of code. But 35:10 will it always have the appropriate 35:12 context of the data structured and how 35:14 it's being passed around etc etc? No. 35:17 And so um console.logs logs is a really 35:20 um good solution or or or way something 35:23 to have in your toolbox to fall back on 35:25 um to kind of really understand what's 35:26 going on in the code here. But then 35:29 following that you may say okay that's 35:30 great Ollie um I can you know use 35:32 console logs but what about if the AI 35:34 does understand context you know 35:36 unsurprisingly here we could um go to 35:38 assist and just like we did with the 35:40 resource we could probably at this 35:43 specific transformer like we did with 35:44 the resource and say fix this piece of 35:46 code for me and it will most likely give 35:49 a good effort at providing a solution. 35:51 Um and I think again we run into that 35:53 same issue that potentially for for 35:54 simpler issues um that would work but 35:57 soon as you get to a point where there's 35:59 you know it's more specific context that 36:01 that you you haven't passed on or takes 36:03 sort of effort to pass on um suddenly 36:05 you can be uh lost at sea with what's 36:08 going on in your code. Um and so having 36:09 the idea of being able to use 36:11 console.logs um is a great place um and 36:13 a great skill to have. 36:16 So, let's just for aesthetic reasons get 36:19 rid of those console logs. Now, we know 36:20 it's working. So, I'm going to delete 36:22 those and save that again. So, that will 36:23 then stop printing out on the console. 36:26 Uh, and just like we did before, let's 36:28 um refresh the page um to double check 36:31 whether if there are any more issues. 36:33 And we now seem to have no more problems 36:35 in the console. So, maybe we're we're 36:37 nearly there. Just to give a brief pause 36:39 um and recap, we have now discussed app 36:42 context, debugging um finding the root 36:45 cause of issues, debugging resource 36:47 queries, and also debugging JavaScript. 36:51 Uh we're going to now finally get into 36:53 the last section, 36:57 which is let's see if we can actually 36:59 submit an access request. So, I'm going 37:02 to click request. I'm going to click 37:04 through on a piece of software. So I'm 37:07 going to select one randomly. I want to 37:09 be an admin test and I'm going to write 37:12 just a test justification. Let's see if 37:14 we can submit this workflow. 37:20 Okay, unfortunately we're still getting 37:23 a problem here. It does seem to be 37:25 creating the access request, but the 37:26 workflow that seems to be triggered um 37:28 to send an approval doesn't seem to be 37:30 working. So just like we did before, 37:32 let's start with the debug tools. Let's 37:34 start going to the error. Let's start by 37:36 clicking onto the um the resource query 37:39 that's triggering this. And like we did 37:41 before, let's run a test to double check 37:43 what the error is. Okay. Yeah, we're 37:45 getting that problem through. Um so with 37:48 this scenario here, um it's only I have 37:51 access to the workflow. We're not going 37:52 to run through the same process of 37:53 duplicating um um dup duplicating the 37:57 JSON and etc, etc. So you can just watch 37:59 along if you have been following up 38:00 until now. 38:02 Uh, and so reading through this error, 38:04 we've got this error true message, no 38:06 recipients defined. We also get the 38:08 workflow run ID. So clearly there's 38:11 something wrong potentially with how 38:12 we've set up this workflow. So we can 38:14 open this workflow from this app and get 38:16 started into debugging workflows. 38:20 So just like we did before, we're going 38:21 to take a moment to understand what's 38:23 going on here. We have a start trigger 38:26 that seems to take in a request ID and 38:29 an email. We then get that the details 38:32 of of that specific request. We then if 38:34 we do get the uh details of the request, 38:37 we then are looking to send an email to 38:39 notify the admin to say you've got an 38:41 approval that you need to make. 38:43 Um and so that seems to be kind of what 38:46 we're trying to achieve here. So just 38:47 like with the app with the debugging 38:49 tools there, we have the run history or 38:50 run logs. Um where we should then be 38:53 able to go into more detail around what 38:55 caused the problem here. Um, 38:57 and what we can do is we can filter the 38:59 runs. Um, and I just want to try and 39:02 find the specific run that I'm looking 39:04 at here. Um, and by clicking onto that 39:08 one I want to investigate, we'll get a 39:10 full history of the uh, what happened. 39:13 Um, so the global all the blocks. So the 39:15 blocks are the individual bits of um, 39:17 code here. Um, so the start trigger, the 39:19 get requests, um, the even the branch 39:21 etc. And you'll see here we get a full 39:24 breakdown of what was triggered, whether 39:25 it was successful, etc., etc. And 39:28 actually, we can see the email admin 39:31 block is the one that's highlighted in 39:33 red. So, this is the issue. And if we go 39:34 to data or JSON, we can see a clearer 39:36 breakdown of this problem. So, error 39:38 true, no recipients defined. If we go to 39:41 the block, we can see here, chances are 39:43 we're not appropriately configuring the 39:46 um email to send the email to send this 39:50 uh to. So a really really useful tool 39:52 within workflows is to go to um inputs 39:55 and within here you'll see basically all 39:56 the information that this block takes in 39:59 um and in opening that you get lots of 40:01 insight into what you're trying to use 40:03 to um get that data and then what it 40:06 evaluated as. Um so we can see here for 40:09 this um who we're sending the email to. 40:11 We've got start trigger.data email. So 40:13 we're pulling from the start trigger and 40:15 we're just getting my full name but not 40:17 my email uh which isn't great. And if we 40:20 double check that so we can see what's 40:22 happening here with the body. We can see 40:23 we've got the raw expression with the 40:25 get request details data um and my name 40:28 um but 40:30 so that seems to be kind of working as 40:31 expected. So let's double check where 40:34 we're pulling this from which is the 40:35 start trigger. So we can click onto the 40:36 start trigger and again for this 40:38 specific workflow run we can view what 40:40 did this start trigger output? What was 40:41 it d what was its data? Um and viewing 40:44 this here we can see next to email again 40:46 we're just sent seem to have sent my 40:48 name in this um trigger uh rather than 40:51 my email. So actually it looks like the 40:53 error lies with the app um not with the 40:57 workflow. So, if we go back to the app, 41:00 um, we can now have a look at this in 41:02 more detail. And we can see here it 41:04 seems to be that we're sending my full 41:06 name. And just like we were doing 41:07 before, you can hover over to see the 41:09 current state. And we can see, yeah, I'm 41:11 sending Ollie Clyde there as my full 41:12 name, not email. But I do have access to 41:14 send my email here. So, let's change 41:16 that. 41:18 Um, and let's run the test again. 41:22 True. Amazing. So, that's now working. 41:24 And hopefully if you have followed along 41:26 um you should have been able to add your 41:28 email to current user and should have 41:30 received an email. Um so just like we 41:33 did before let's refresh and and finally 41:35 let's see if Jerry has made any more 41:37 problems. Um so I can see here I've now 41:40 got my pending request at the bot. Let's 41:43 try and approve that. So if I click on 41:45 to that pending request um I can now 41:50 determine whether to reject it or 41:52 approve it. Let's give myself access. 41:54 Let's approve it. Brilliant. Amazing. 41:56 And let's now turn to approved. So, it 41:57 looks like everything's working um as 42:00 expected. 42:02 Amazing. Thanks so much for following 42:04 along. Um I hope you found that 42:07 uh kind of useful and covered some areas 42:10 that either you haven't seen before um 42:12 or some new tips or tricks that you can 42:15 now use when working um in retail 42:17 yourself. Uh to give a little recap of 42:19 some of the main points I I wanted to 42:21 get across. Um, one, the importance of 42:25 starting broad um, and then going deep. 42:28 Um, effectively using things like assist 42:31 to understand the bigger picture of how 42:33 the app works and then going from the 42:35 debugging tools to the error um, to then 42:37 kind of work your way back to um, the 42:39 specific issues or like we found with 42:40 the resource query, what are the the 42:42 most likely um, uh, issues here and then 42:46 work our way picking them off before 42:48 going into the deep depth of reading 42:50 documentation. um the importance of 42:52 testing incrementally. Everything we 42:54 went through today would make one change 42:55 and then test. Um and so uh not trying 42:58 to fix everything at once, but iterating 43:00 is is really useful and important when 43:03 debugging, understanding dependencies, 43:05 checking dependencies, using the state 43:07 tab, understanding state, I think is a 43:09 really important part of debugging. Um 43:11 and so something to be familiar with. Um 43:14 and finally, the importance of reading 43:16 the documentation. Uh, I don't know if I 43:18 mentioned this already, but when I was 43:20 first started to um um get into software 43:22 development, biggest piece of advice I'd 43:24 got was always read the docs. Um, 43:26 obviously that's changing now with how 43:27 good AI is at um summarizing things for 43:30 you. Um, but 43:32 um effectively the amount of times I've 43:34 gone to set up a resource, skim the 43:35 docs, think I thought I understood 43:37 what's going on and then ended up um 43:38 having a really common error that I 43:40 could have avoided um uh earlier on. 43:44 Lovely. So, thanks so much for following 43:46 along and listening. Um, looking at the 43:49 time, we do have some some um uh some 43:53 extra bit at the end to talk through any 43:55 questions um that you may have. Um, I 43:57 don't know if there any in particular 43:58 that cropped up that we can get into um 44:00 straight away. 44:11 I think Mike had one question about uh 44:13 the header um in the resource 44:17 configuration. So maybe you could show 44:18 that on the screen. 44:22 >> Yes. Um so if I go back to that resource 44:26 query in the header that I have set up 44:28 here. Um 44:31 let me see if I can get the specifics of 44:33 the question. 44:51 Um, so yeah. Yeah. Any questions around 44:53 the header? The solution was to add in 44:55 the X API key. Um, which 44:59 >> yeah, 45:01 >> if you could show the uh if you edit the 45:03 resource configuration, how you can 45:04 place it there as well. uh so where it 45:06 should be for best 45:07 >> practice. Yeah. Yeah. So um so for best 45:10 practice um by editing the resource it 45:13 just means that anytime this resource is 45:15 used without within um any app um it 45:18 will then by default have that API key. 45:20 And so we could do the same here XP API 45:22 key here and then set it um just like we 45:26 did before. The only difference being 45:27 actually it's defined as an environment 45:29 variable here. 45:31 Um so we can see that postman API key 45:33 rather than within the app itself which 45:35 is stored in the retool context. Um so 45:39 um just explain that in detail there's a 45:40 slight um difference there set as an 45:42 environment variable um rather than a 45:44 within the retool context. Um so 45:46 effectively what this means is you as an 45:48 admin can set it up of here are the 45:49 details of how you can connect to this 45:50 resource and then you know you can then 45:53 um they can use that without knowing the 45:54 API key or it being exposed on the 45:57 within the app itself. um but they can 45:59 then still access the data or maybe 46:00 create even create their own requests um 46:02 to this endpoint. 46:06 >> Uh we had one question from uh Ollie 46:08 which is how do you know which queries 46:10 run on page load? 46:13 >> Great question. Um 46:16 so 46:17 on timeline here the the um so that was 46:21 in in the debugging tools um the 46:23 timeline tab. 46:25 Um, effectively if you refresh the page 46:31 um, and go to the timeline tab, this 46:32 will show you basically all of the ones 46:34 that that run kind of on page load. Um, 46:37 and typically it's also ones, you know, 46:39 most likely. Um, if you go to any 46:42 resource query here, 46:44 um, you should be able to view if we 46:46 were to say get request query, um, you 46:51 can look at the run behavior as well. 46:53 and you'll you'll be able to see okay 46:54 this run behavior is that it's going to 46:56 um kind of run on page load and so it's 46:58 automatic rather than something that's 47:00 done manually. So you're manually 47:01 tricking triggering it you know through 47:02 an event handler um whether you know 47:04 whether within a button or whatever it 47:06 may be. Um but yeah technically speaking 47:08 these are all on that refresh on that 47:10 page load. Um and yeah out of curiosity 47:13 as well you can sort of see some 47:14 information around um the timeline of 47:18 that load. Um, and so, um, yeah, as I 47:20 mentioned, you can use this to go into 47:22 more detail around, um, what could be 47:24 causing, um, uh, 47:28 performance issues within your 47:29 application. 47:42 Nice. Um, within the instructions, I've 47:44 also included some, um, useful 47:46 resources. Um effectively they're just a 47:48 rundown of you know the debugging tools 47:50 in the app. Um the run history setup and 47:52 workflows as well as kind of common 47:54 resource connection um errors that we 47:56 see. Um so they're very useful to um 47:59 have a read yourself uh and kind of use 48:02 when debugging and retool. 48:09 >> I think that's it for questions. 48:11 >> Nice. Um brilliant. 48:17 So to finish for the next event that 48:20 we're that we're running um we have a uh 48:23 we're running a retail summit uh in the 48:25 shard um March 26th um don't know m if 48:28 there are any more specifics on this but 48:30 if you if anyone wants to scan the QR 48:32 code um they can get some more details 48:34 around how they can register um find out 48:37 what's going on 48:41 and it would be brilliant to see you 48:43 Yeah. 48:59 Can see a question on 49:22 Okay, brilliant. Well, to wrap up there, 49:24 um, thanks so much for joining. Um, and 49:26 yeah, hopefully see you at Retall 49:28 Summit. Thank you so much.