00:00:20.840
Thank you for being here for our talk, "Don't be afraid of the scary red error messages; they're actually our friends."
00:00:28.080
We're here to change your mind about failure, how you respond to it, and give you some tips and tools for how to deal with it in your own programming adventures.
00:00:40.620
In my first stand-up with a brand new client, imagine this client is a very posh one. I mean there’s a lot of argyle and tweed involved. This is what I showed them in my first stand-up. It was my turn to share, and I said, "Alright, everybody, this is the big Rails error page I'm currently contending with. I plan to figure out what's going wrong," and then I stopped sharing. We moved on with stand-up.
00:01:06.060
Later, after the meeting, my project manager came to me and said, "That was amazing!" I was puzzled and asked, "What was?" because I had no idea what he was talking about. He pointed out that I had shared my issues openly, unlike everyone else, who had basically said, "No blockers," and we moved on. I was doing things differently.
00:01:19.740
You see, I grew up as an artist, and so failure has actually been my end goal. Aha! Another artist in the crowd, I can tell. Many of you might not know this, but the starving artist stereotype is pervasive; it is what all budding artists are told to expect from their careers.
00:01:33.960
I didn't realize that my unabashed nature when it came to failure would become such a blessing when I transitioned into being a software engineer. What I've learned from this journey, from junior to senior level, is that the skill of openly sharing one's progress, including the failures, is not common, but it can be taught. In this talk, we'll tackle how to normalize failure and then give you some tips on how to handle them in your own practice.
00:02:10.200
We'll have some time at the end for questions, so if you think of any, please save them till the end. Thanks! Failures, errors, and broken tests are a natural part of the development process. This talk is all about how to embrace them rather than fear them, and how to turn these hurdles in your path into stepping stones to get you where you want to go.
00:02:36.900
My name is Kait Sewell, and I’m a senior software engineer at scientist.com. We help make digital ideas a reality and are primarily a Rails shop with some React, JavaScript, and Docker-based environments. Soft Serve is the software consultancy of scientist.com and we’re in a rare opportunity where we're looking to bring on some bigger clients.
00:03:01.440
Scientist.com is a company that helps researchers get science done on demand, and my colleague and I work for the Department that assists our clients with their software engineering needs. This is Shayna Moore; she's a more experienced senior software engineer, and you all are lucky to get to listen to her speak later.
00:03:38.580
The first thing I want to do is normalize failure. Handling error messages is just one aspect of dealing with failures in software development. Failures can occur at various levels of the development process such as design, implementation, testing, or deployment. Dealing with failures effectively requires a mindset that views failures as opportunities for learning and improvement, rather than as sources of blame or shame.
00:04:09.180
To overcome this, one must embrace a growth mindset. I encourage you to see failures as opportunities for growth, not as personal flaws or setbacks. A failure is not a waste of time; it is an experience where hopefully you learned something. Even experienced programmers make mistakes; the key is to learn from these failures and use that knowledge to improve.
00:04:37.740
The problem we face is that for most people, sharing failure is incredibly uncomfortable. When it comes to what we share openly, we tend to highlight our successes on social media rather than mundane tasks like a trip to the grocery store. This is where we have to recondition ourselves to see failure in a new light. Rewiring your brain is not easy, but it's doable.
00:05:11.220
All sorts of books have been written about how to hack your brain and retrain it. What I'm asking from you is to lean into the idea of the cognitive triangle: if you change your feelings about something, you can change your thoughts about it, and if you change your thoughts about it, you can change your feelings about it, which in turn will change your actions.
00:05:34.760
This talk is about how you respond to failure. It’s something to be embraced—welcome it! Revel in it, even. Changing how you feel about failure will take time and effort; it won't happen overnight. However, the building of this skill will pay off when you see your progress speed up, as you're no longer held back by the fear of making a mistake.
00:06:07.320
Anyway, Git history can help you if you ever need it. You can always go back to where it was working before and begin the problem-solving process again with new information. Relax in the knowledge that you can't really break it beyond repair. It's safe to experiment; in fact, it's encouraged. Failing will help you and your code become more resilient.
00:06:37.740
Embracing a growth mindset in your skill development will set you up for success. I can’t remember exactly when, but somewhere in my teens, I decided I liked being wrong. Not only did I like being wrong, but it also became my new ethos. I liked being proven wrong because it gave me the chance to learn something.
00:07:03.740
I don't know what made me realize this, but at the end of it, after the embarrassment, I was smarter than I was before being wrong. If no one had proven me wrong, I would have just continued being wrong until someone or something helped me fix it. The embarrassment of being wrong diminishes with time, practice, and a different outlook.
00:07:39.600
If you want to know more about growth mindsets, definitely check out Carol Dweck's work. Speaking of famous people, this is a small list of celebrities, all of whom were not born into fame but made it happen for themselves despite countless failures. Except for Edison, he counted his failures. These are people who worked hard to achieve their levels of success; even Edison, who was notoriously litigious, could reframe failure as a learning experience.
00:08:50.400
However, it's ironic that while he could reframe failure, there's still such a stigma for us humans that he didn't want to admit it was happening. Now, here's the important caveat: you can do all the reframing you want, but if you don't learn anything from your mistakes, then you are wasting your time. To truly learn from your mistakes, you can't just sweep them under the rug; you need to sit with them for a while and be open about them.
00:09:25.380
Keeping that gained knowledge to yourself will hinder your growth from the experience. The hardest part of my job is admitting when I fail to find a solution and having to ask for help. I still struggle with my pride every time, and that's okay.
00:09:57.300
Being a work in progress is a shared experience. Even in last week's sprint, I hated admitting I was stuck on tickets and needed help. When I was a junior, it would take days for me to admit I needed help; I wanted so badly to prove that I could do my job. It was part of becoming a senior where I realized that my job was to fail fast, to venture out into the wilderness of what was possible and what wasn’t, and to fail as quickly as possible.
00:10:39.000
This way, we could move on to the next challenge. This is how progress is made—minds coming together to find a solution where there was previously only hypothesis and jumbled data. Getting used to failing and maintaining the grit to keep going are skills I developed over time.
00:11:19.440
It took me a long time to realize how much of a strength this was. It was actually when I was taken aside by that project manager I mentioned at the beginning of the talk, and he told me how much of an impact my sharing my failure made that I realized this was a skill I needed to hone.
00:11:56.420
Frequent and repeated failures are often where I learn the most. I like to use test-driven development (TDD) to help me understand what I'm trying to solve. I may not know what I need to do to fix it, but I know I can actively introduce failures. Starting from a place of failure gives me a freedom I wouldn’t have otherwise because it removes the risk from my experiments.
00:12:44.640
With TDD, I can just run my specs over and over again until the pieces start to come together. Now, to help you piece things together, I’ll hand it over to my colleague, Shayna Moore.
00:13:04.890
Okay, hello! Thank you, Kate, for the kind words. If we’re going to encourage you to fail fast, we’d like to provide you with some practical tips for how to handle error messages.
00:13:17.400
We know that error messages can be frustrating and stressful, especially for junior developers due to lack of experience, fear of failure, lack of confidence, and time pressure; some of the things that Kate has already mentioned. It might not help that many of the error messages you’ll see are red, which can trigger flashbacks to negative experiences like the one Kate just described.
00:13:45.300
But remember, they are red to stand out, to get your attention, and ultimately to help. Stop signs are red for the same reason. Could you imagine a world without them? My guess is it would be a lot more chaotic than usual, especially if you live in a city.
00:14:12.000
So instead of being afraid of these messages, let’s embrace them! Treat them as learning opportunities. I’ll cover nine ideas. The first seems kind of obvious, but it doesn't always happen: make sure you read and understand the error message. What is it trying to tell you? Sometimes, if you pay close enough attention, the solution lies within the error itself.
00:14:47.400
In this example, something went wrong when I called Shuffle on an array of fruits. The purple is the error type, the green is the error message, and the yellow is the Ruby interpreter offering a suggestion. So, I received a no method error: "Shuffle does not exist; did you mean Shuffle?" Yes, I did! It was a simple typo, which is really easy to miss.
00:15:20.760
Secondly, we want to identify the source of the error. One of my favorite parts of an error message is that they often come with a stack trace. A stack trace is a report displaying the sequence of function calls that led to the exception. They contain a lot of helpful information, like the file and the line number where the exception occurred.
00:15:49.140
In this Pig Latin converter program called Piggott, I received a no method error when I ran the program. The no method error said: "undefined method split for the number 42." Looking at this stack trace, I can see that the error occurred on line three of the Piggott file in a method called picket.
00:16:11.520
Using tips we'll discuss later, I learned that the method split is a Ruby method for strings, and it can’t be used on integers. If you can remember this example, we will revisit it. I intentionally raised an error just for demonstration purposes, resulting in a runtime error.
00:16:49.380
Looking back at the stack trace, we can see that method C was called by line six of method B, which in turn was called by line two of method A, and ultimately it was called on line 13 of the main program. Remember this example as well; we will see it again soon.
00:17:22.560
So far, all of my examples have been very simple and contrived. What do you do when your stack trace looks like this? Your reaction might be confusion. The best thing you can do is to slow down and read it carefully.
00:17:49.140
I received this error when I ran seeds in a Rails application. The task aborted due to a type error. Can you spot the offending line? It's here, and our heuristic to help you find it is to look for where the lines change from the bundled gems to where the lines start with 'app,' assuming the error comes from your application.
00:18:08.520
In this error, we can see it occurred in the decorate works type method on line 11 of the child indexer RB file, in a gem called triple if print that I had cloned to my vendor directory for local development. That's a lot of helpful information and such a time saver. When we say that error messages are friends, this is exactly what we need, and we should be grateful for them instead of scared.
00:18:53.880
I wanted to include this example because as a Rails developer, you'll likely see or have seen this error page a lot. In fact, Kate shared one earlier. As a junior Dev, I took this error page for granted and didn’t realize how jam-packed with helpful information it was. It’s also interactive.
00:19:11.880
Starting from the top, it tells you the error type and specifies the controller and action it came from. In this case, it indicates that this error occurred on line 11 in a partial called sidebar. The error message also includes a helpful "Did you mean?" statement.
00:19:49.680
The extracted source section highlights where the actual error occurred. I refer to this as context. Next, we have the trace templates, which in this example shows that the dashboard is responsible for rendering the sidebar partial. We can see the root of the application.
00:20:23.520
The exciting part, in my opinion, is that it's interactive. You can click on each link; it will unfold the stack trace and you can examine what was happening in your code at that particular point. You will see that I included an example for how this page looks if you have a routing error, which is also very helpful.
00:20:50.280
From there, you will be able to filter and search for all the available routes in your application. It includes the route helper, available HTTP verbs, the path, and the controller and actions responsible. To summarize, the error page is incredibly helpful, and I highly encourage you to play around with it the next time you see one.
00:21:30.960
For debugging tools, as Rails developers, we have several options. Some popular ones include Pry, Byebug, Web Console, and built-in debuggers. Debugging tools allow us to set breakpoints at specific points in our program, meaning the program will pause, and from there, you can execute your code line by line.
00:21:53.220
You can inspect variables and values along the way. Revisiting this Pig Latin program, remember that I got a no method error previously. We were able to follow the stack trace and identify that on line 25, I passed an integer instead of a string. Let's pretend I didn’t know this so we have an opportunity to use a debugger.
00:22:38.160
The first thing I’d do is set a breakpoint near the offending line, which I would identify from the stack trace, and then I would start my program. Personally, I would be interested in inspecting the parameter named 'str,' which usually stands for string. When I ask for its value, I get the number 42—definitely a clue that something's not right here. Next, I could run the line where I actually failed.
00:23:54.540
I could use the keyword 'next' for that, but instead, I use 'play l' and the line number to execute that line, which revealed the error we saw earlier. 'Play l' stands for 'play line' and is a Pry-specific tool that I use often. The point is to find a debugging tool you like, learn it well, and ensure that your debugging can be efficient.
00:24:47.520
Now, returning to our simple stack trace example, I’d like to share four of my favorite debugging methods.
00:25:06.960
The first method is 'caller,' which generates the stack trace report as we saw earlier. The stack trace example clearly reveals that method C was called by method B, which was in turn called by method A, and so on.
00:25:41.400
The next method, Source Location, was mentioned yesterday in a keynote, and I was excited because I use it often. It’s incredibly valuable; if you’re in a large application with lots of files, it can show you exactly where everything is defined. In this example, I called it on method C, and it revealed the file and line number where it was defined.
00:26:06.720
The next tool is Pry-specific, called 'source.' It’s similar to Source Location, but instead of showing where it is located, it returns the method definition itself. If I were to type puts and call 'source' on method A, it would return the contents of the method.
00:26:37.740
Lastly, there's 'backtrace.' This is useful when you’re rescuing exceptions and need to produce the stack trace for that particular error. Hopefully, you’re all still with me.
00:27:09.120
We are nearly halfway there. The next three points can be lumped under a common problems checklist, and I would argue that these will be the most frequent issues you encounter as a junior or new programmer. However, spoiler alert: many of the issues I face as a senior developer also trace back to these three points.
00:27:49.920
The first one isn't too bad because if you have a syntax error, your Ruby code won’t run. However, this can be frustrating because it’s easy to overlook. Has anyone ever stared at a problem, trying to figure out what’s wrong, only to realize you’re missing a comma?
00:28:10.920
To avoid this, use a good text editor or IDE (Integrated Development Environment), or a plugin that highlights your syntax errors as you type. In this example, I encountered an error when running a program due to a syntax error, which was actually quite helpful. But I didn’t need to get that far because I use Visual Studio Code.
00:28:46.620
It highlights my syntax errors as I type. In this case, I was missing a closing parenthesis, which it flagged with a red highlight. Once I fixed the problem, as shown in the bottom example, there are no more red highlights, and I can run the program successfully.
00:29:24.060
Common sources of errors also include incorrect inputs and outputs. For example, this add numbers program should return the sum of two arguments. However, when I ran it, it caused a type error saying a string can't be coerced into an integer. Looking at line seven, I passed two different data types: an integer and a string.
00:29:48.540
Every time you think you know what to expect, be aware of these possible pitfalls. Now, what if I need a logic mistake that impacts my code's output? In my add numbers method, I mistakenly wrote A minus B instead of A plus B. If I called it with five and five, I’d expect a return of 10, but it returned zero, causing a serious bug in my application.
00:30:14.580
Even if your code is free of syntax errors and runs without crashing, and your inputs look fine, you can still have logical errors leading to unexpected behaviors in your program. The Ruby interpreter will still execute it.
00:30:45.240
A common strategy to catch both logical and output errors early is to use TDD (Test Driven Development), which is something Kate mentioned earlier. In this practice, we write our tests first before any code.
00:31:11.580
This ensures our programs behave exactly as we expect. For example, I created a spec that expected the add numbers method to return 10 when called with five and five. I ran the spec and received an error, as I hadn’t written any logic at all. The next step would be to write the minimum amount of code needed for the spec to pass.
00:31:32.640
So I wrote A plus B in my code, re-ran the program, and it passed. With this type of workflow, I would have definitely caught the logical and output errors from before.
00:32:01.320
Now, if you encounter a particularly hard and confusing error message, this is the time to search for online resources for guidance. There are plenty of online forums, blogs, and documentation sites. Some popular choices include Stack Overflow and various documentation for languages, frameworks, and gems.
00:32:25.550
However, I would recommend avoiding the temptation to just copy and paste. Try to genuinely understand your code when you find a solution. Ask yourself if what you’re reading is relevant to your use case.
00:32:41.780
When reading documentation, ensure you're looking at the correct version. Oftentimes, the success of finding a solution will depend on how well you can Google.
00:33:07.440
Another thing you can try that is new and exciting is AI tools. I’ll preface this by saying I don’t have much experience with GitHub’s Copilot; I just gained access. Therefore, I’ll focus on ChatGPT.
00:33:24.840
Copilot is designed for developers and understands the context of your code, while ChatGPT is more general. I’m still learning the best ways to use it and ask questions.
00:33:43.560
In the previous example, I asked ChatGPT what the error meant: "Oh, it's a string; it can't be coerced into an integer." And when I asked, I received a helpful response that encouraged me to figure out what I needed to do.
00:34:09.540
ChatGPT could be a valuable tool for gaining guidance on various issues, but it’s important to mention some cautions.
00:34:27.720
First, don’t treat it as a source of truth; it can be wrong. Personally, I’m currently more comfortable asking it questions.
00:34:39.840
Exercise caution when copying and pasting your code into ChatGPT due to the terms of use which allows them to use your information to train AI models. You may have seen headlines about companies' data leaks due to employees using ChatGPT.
00:35:04.680
As a general rule of thumb, don’t input private or sensitive data. I highly recommend a session from Josh Puetz that covers best practices for programming fairly with AI.
00:35:27.720
Lastly, Eric Houston, a Twitch streamer and YouTuber, has fascinating content on using Copilot. We are almost done. You’ve tried all the things by now, but if you still don’t have a solution, I’d recommend stepping away from your computer to take a break.
00:36:03.840
When you reconnect and still feel stuck, be humble and ask for help. This is the time to share your error message with your Dev team. In our company, we created a Slack engineering channel for this purpose.
00:36:40.740
This channel has become a repository of questions from everyone on the team. Chances are someone may have already encountered the problem and can quickly jump in to help you.
00:37:03.510
In an example, I asked a question, and my great co-presenter, Kate, responded in the thread, offering to be a second pair of eyes. Often, that’s all you need.
00:37:25.440
But when you do find a solution, I recommend ending your question thread with ‘solved’ or a similar keyword. This gives others quick breadcrumbs to follow and saves a lot of time.
00:37:46.320
By documenting what you’ve encountered while it’s still fresh in your brain, the learning process sinks in deeper. That’s all I have for you today. Hopefully, we’ve empowered you with the right mindset and tools to create a troubleshooting framework that will help you embrace the failures and challenges you encounter as a developer.
00:38:09.480
In doing so, you will become more confident, skilled, and successful in your work. Your programs will become more robust and reliable, and your customers and team will be happier with the high-quality code and growth-minded attitudes you’ll contribute.
00:38:35.279
So, now we’ve got some time for Q&A. Does anyone have any questions?
00:38:40.919
What I would do first is repeat the question so everyone can hear it. The question is, if you're working with an older version of Rails and it isn't an updated code base, how do you find the documentation you need?
00:39:09.480
Well, I recommend going to the Rails Guides and finding the specific version of Rails you’re working with. Go through how things were built in that version.
00:39:30.660
Alternatively, if it’s not Rails but an old gem, I would visit GitHub to ensure you’re looking at the version of the code corresponding to your project. I can’t tell you how often I’ve looked at the wrong main branch.
00:39:50.160
The things have changed too much over time. Thus, check your versions and be sure you're reading documentation specific to your version. Searching for the specific version you're working with can lead you to what you need.
00:40:09.960
The next question is about mentoring—if you consider yourself a senior developer and want to help a junior developer but don’t want to hand them the answers, what should you do?
00:40:31.680
I would suggest that you hold your tongue. It is tough sometimes not to just share information. You want them to succeed quickly, but they will retain more if they uncover the answers themselves.
00:40:51.720
It’s important to equip them with the problem-solving skills to get there. What I usually do is walk through the problem-solving process with them, guiding them through their searches until they arrive at the solution themselves.
00:41:12.420
Sheila mentioned that it’s often more valuable than just giving them the answer outright. You’re there to guide, and often, you may not know precisely how to solve the problem, but having the skills to find the right answer is crucial.
00:41:32.160
Thank you again for attending our talk! We work for Soft Serve by scientist.com, and if you'd like to work with us, please feel free to reach out. Enjoy the conference!