To Error, or Not to Error, that is the Question

Posted by on September 13, 2019

Setting the scene

You’ve got a great new feature – you’ve spent days and months testing and producing it and it’s ready. You’re ready to deploy, turn on the feature switch and GO GO GO. You know people are going to love it – and you’ve thought of all the possible issues that could arise.

But disaster strikes – you’re throwing exceptions and things don’t seem to be working the same as you found in your testing – what’s different you ask? Could it be the users? Could it be a different configuration? Or could it be your code?

Now nine times out of ten it’s not the user, it’s you! They are happily typing or clicking when bang, they get an error. Now, if you’ve done your job right these errors should be gracefully handled, the user should be told what is wrong and receive a reasonably helpful error message. But this is not always the case. So in this article I’m going to explore what I think makes a useful error and what you should do when things go wrong.

A lovely error written by yours truly

What is a Useful Error?

Over the summer I’ve been working on some cool projects (Expenses Uploads and Practice Transfers) that require a high degree of user input. Sometimes through misunderstanding or no fault of their own users encounter error. Especially within our Expenses and Mileage upload project we decided that we needed to provide “useful” errors to users to help them and our support teams diagnose and fix issues with their uploads.

This is when we need to come to a decision about what makes an error “useful”. I thought to myself: what are the key things I need to think of when providing an error? So I came up with 3 key criteria – specificity, usefulness and actionability. I would add that these criteria are not exhaustive and you may disagree with them but they are what I think makes a good error message.

Specificity

What is specificity? Well, we want our error messages to tell the user precisely where the issue is. Is it a general issue with a file uploaded, is it an issue with a line in the file or an email address entered? The user needs to know – if they don’t they can’t be expected to guess and fix it!

For us, this meant highlighting from which line in a file issues have arisen, giving the user the context of where the issue has happened. Or highlighting the specific field in which the user has mistyped an input – so they can see exactly where the issue is. We just need to tell them where to look to fix the issue.

Usefulness

If an error is not useful, what is its purpose? Sufficient details and information should be provided to the user at the time without overwhelming them with information. They should have enough detail to know what has gone wrong in a way that guides them towards the correct input.

Within the projects that I’ve been working on I really thought about this quite hard – we always, where possible, want the errors we produce to be useful. Sometimes this is difficult, as we’re showing the same error for multiple failure conditions and therefore have had to make a call about what is the best error to show. At other times it’s a process of translating from our technical speak to something that is more user friendly. For me this is when it is great to have someone else, like a product manager, to be able to ask what they think is best and guide what would be useful for users.

I like to think this is very useful and specific.

Actionability

All errors – apart from the very exceptional – should have some way for the user to continue forward and get themselves back on track! We should always give the user the opportunity to know what they are able to do – be it giving a list of input or linking to a help article.

Sometimes this can be the hardest thing to do: provide some action for the user to carry out in response to the error. We worked hard as a team to be able to provide users with lists of valid and accepted input, and to let them know if they cannot continue down the path they have set down and provided them with Knowledge Base links to help. I would argue this is the most important part of an error message as it provides the user with something to do and gives them the help they need!

So what should you do When Things Go Wrong?

In an ideal world we would be able to consider all potential errors and be prepared to deal with them, but sometimes you’ve not considered a case or thought that something like that could happen. This may cause unexpected funkiness and may end up making your feature work in unexpected ways.

This happened to me – and it can happen to you too! So what should you do? In my mind having some error is better than no error. If you can’t provide the full 3 key criteria that I’ve discussed but you can provide something – for example “there has been an unexpected error and our engineers are looking into it” – it is much, much better than nothing. If you don’t give any feedback when something goes wrong, users may get the wrong idea and think that what they were trying to do has succeeded even when it has not!

Conclusion

Errors are part and parcel of software development, and making them useful to users can be difficult. I’ve discussed 3 key areas that I think are important to think about when creating error messages – specificity, usefulness, and actionability. But at the end of the day – if something goes wrong just return an error. Your users will thank you for it!

How we make architectural decisions

Posted by on September 11, 2019

“Change is the only constant in life.”

—Heraclitus


The software we build at FreeAgent is constantly changing and evolving. The requirements of our software can change for a wide variety of reasons, including: scalability concerns, changes to the law or organisational changes. It’s impossible to list all the reasons why your software might have to change, but it’s crucial to acknowledge that it WILL change.

In order to clearly communicate the need for change and to keep track of any decisions made along the way, we have employed a process that works extremely well for larger engineering teams. For reference, our engineering team consists of over 80 talented people, that includes engineers, managers and testers.

Request For Discussion (RFD)

Every significant change needs to be communicated with its internal stakeholders. Whilst smaller changes can usually be decided within the team, larger changes typically require input from other teams as it may affect the area they are responsible for.

Quality work can only be achieved if you have quality time to focus on it. We want our engineers to have this quality time to build exceptional software that our customers love. However, that means they won’t always be available to join the conversation immediately. For that reason we use asynchronous ways of communicating this information. This allows participants to digest the information before responding. We want to avoid snap decisions.

For our purposes, we use Google Docs to write these proposals in a document which we call a Request for Discussion (RFD). Google Docs is great for collaboration. It allows us to review content in our own time and leave comments whenever a section needs clarification, or to provide valuable feedback.

All RFDs that we write follow a predefined structure which enables us to clearly communicate the intention and desired outcome of a proposed change. The outline of the structure is:

  • Header – contains the title, a unique ID (e.g. RFD-2019-0098), list of authors, the name of the owner, list of stakeholders, the date and the current state (draft, review, accepted, implemented, abandoned).
  • Motivation – this is where we explain the reason why the document exists; what problem are we trying to solve?
  • Research – a description of the current state and how possible solutions were evaluated.
  • Possible solutions/actions  – a list of solutions or actions to consider to solve the problem. Depending on the context more than one may apply.
  • Summary – a summary of the entire document and a recommended solution with its consequences.
  • Questions – opportunity for readers to leave questions that will be answered by the authors.
  • References – a list of links to relevant resources.
  • Appendix – collection of diagrams, code snippets or tables to support the document. We extract this into a separate section to preserve the pace of reading.

Here’s an example template:

RFD Template

Once an RFD is ready to be reviewed, we post a message in our internal discussion platform (powered by Discourse). This will send a notification to the engineering team via email and Slack. At this point, we also alert the stakeholders to make them aware that their input is required to make a decision. This is a manual process at the moment but we are aiming to find a solution to automate this step in the future.

Architecture Forum

We found that changes with a wider impact are easier to discuss with an additional in-person conversation. If you have read Ed Catmull’s fantastic book, Creativity Inc., you may be familiar with the concept of the Braintrust. We have taken some inspiration from this concept and used it to help us make large-scale architecture decisions.

We invite several senior or principal engineers with a diverse skill set to these meetings. Every participant is required to read the supporting RFD first, before joining the meeting. This ensures that everyone is on the same page and shares the same context. Furthermore, we don’t need to reiterate information that would take away time from the actual conversation.

These meetings allow all participants and stakeholders to ask questions that couldn’t be answered via comments in the RFD, and delve right into the details with the author. These meetings have a clear goal: make a decision. Ideally, this would mean that we approve or reject an RFD but this is not always possible. If an RFD can’t be approved or rejected at this point, we define clear actions, which need to have an owner, to move the development of this request forward.

Keeping track of decisions

As your architecture and organisation changes, it’s important to keep track of the decisions that have been made over time. The decision should provide enough context to make it clear why it was made, even months later. Perhaps, at the time, there were constraints such as budget limitations or the lack of a piece of technology.

We track these decisions in our RFD Register spreadsheet and they serve as a formal architecture decision record. The state of the decision is also updated in the RFD accordingly. We communicate any changes or decisions via our discourse-powered discussion platform for increased visibility.

Screenshot of RFD Register Spreadsheet
RFD Register Spreadsheet

It is good practice to record any changes in a lightweight format and in your codebase as well. This will be beneficial for any engineers joining the team and it also keeps your decisions in sync with your changes.

We produce a lot of RFDs! Over 100 have been written in the first 8 months of 2019! This shows the importance of being able to track the state of each decision.

Conclusion

Making architectural decisions is difficult and requires a lot of coordination between your engineers. Below is a list of steps that work very well for us:

  1. Give people context, i.e. write it down.
  2. Encourage asynchronous communication to give people the space to think their input through.
  3. If needed, get everyone in a (virtual) room to ask for advice.
  4. Keep track of your decisions.

Although our decision making progress works great most of the time, we still struggle in some areas. Naming decision owners in particular is something we would like to introduce, to reduce the time to make a decision. It is also sometimes unclear when a discussion requires an additional conversation at the Architecture Forum.


How does your organisation make and track architectural decisions? Please let us know in the comments.

From Computer Science student to Software Engineering intern

Posted by on September 2, 2019

Hi folks, my name’s Iain, and I’m one of the few interns you haven’t yet heard from this summer.

In my last three months on the intern team I’ve embarked on a whistle stop tour around the FreeAgent application, from user facing emails to developer only APIs. In that time, I’ve learnt a few softer skills that I never would have had the opportunity to whilst I was at university, and I’d like to take this opportunity to share them with you.

Some of these I wish I learned before coming to FreeAgent, whilst others are simply skills I don’t think it’s possible to learn in a university environment – of course, your mileage and experience may vary.

Without further ado:

I wonder what they’re all watching? Photo by davide ragusa on Unsplash

1. Who is your customer?

AKA: Remember your audience

The software you write is intended for somebody, so it’s important that you keep them in mind as you work. The requirements set out to you may not always capture the full extent of the effects your code will have (though you can always hope that they get close).

There may also be more than one person you’re developing for. If you implement a customer facing feature, how easy will it be to support the users using it in the long run? How easy will it to be fix, or upgrade, by the engineers who come after you?

When you’re at university, the audience of your software is often limited. Rarely will the output of something you write for marks ever be seen by anyone other than you and your marker. There is no ongoing support burden for your submission. There is no ongoing engineering burden for what you have written. This can lead to a style of development that doesn’t lend itself to maintainable, useable code. That doesn’t necessarily mean you need to change your entire perspective on how you work at university (or that I’m any better when it comes to practicals), but it’s definitely a sentiment to keep in mind when graduating to writing software professionally.

I will concede that this guy is very cool. Photo by Alyssa Kibiloski on Unsplash

2. Cool tricks aren’t always that cool

AKA: Maintainability and readability are what’s really hip kids

This one is another comment on how you might end up writing code at university. Outside of a few group projects (which often arrive later in a CompSci student’s time at university), the grand majority of what you’ve written will have been written alone, and with little expectation of ever looking at it again once you’re finished with it.

Consciously or not, the code quality of what you write can suffer because of this. Even with a well enforced style guide at your university, practicals often aren’t designed or marked with maintainability in mind. 

Another thing to consider when coding professionally is the balance between performance and readability. What is the maintainability or readability cost of optimizing that piece of code? Especially when considered in the context of exactly how much performance you’ll gain. 

That’s not to say that performance isn’t worth considering. Understanding the complexity of what you’re writing is important, and sometimes there isn’t a simple answer to what you’re trying to solve. Similarly, there can and will be times where those extra few seconds, or milliseconds, count. Just don’t get hung up on showing off the latest piece of coding trickery you’ve learned at every opportunity.

Where do people get all these stickers? I want some. Photo by Tim Gouw on Unsplash

3. Take a step back every now and then

AKA: No, running it again won’t magically fix it

This one applies no matter where you are or what you’re working on: sometimes you reach the point of diminishing returns, where applying more effort to a problem isn’t going to get it solved anytime soon.

Whether it’s stress, frustration at yourself, frustration at your code, tiredness, or all of the above, digging deeper and throwing yourself at the problem again and again isn’t going to fix things. I won’t pretend to know what works for you, there’s no magic bullet for de-stressing – but I can say that stopping and giving yourself time to think about something that isn’t the problem will save you a hell of a lot of time in the long run.

One problem with this advice is that it’s very difficult to tell when you’ve fallen into this situation. This is part of the problem itself, in that your focus is so dedicated to one thing you tend to lose sight of everything else. Unfortunately, everyone’s ‘tells’ are different, so they’re something you’ll have to figure out for yourself. For me, I usually know I’ve reached this point when I re-run or re-compile something without changing anything, hoping this time it’ll work.

I wonder if they’re talking about the paintings. Photo by Antenna on Unsplash

4. Talk to people

AKA: Listen to people

Conversations are the best way to improve everyone’s understanding. They provide the opportunity for you to also take a minute, and take stock of what you know, what you’re doing and what you plan to do.

Talking with others, and more importantly listening to others, also lets you see things from a perspective you may not have. Most everyone you meet will be happy to share their experiences, whether they be colleagues or fellow students, and their insights can provide helpful warnings or new ideas.

Similarly, remember to ask questions! In university, the people to ask are your lecturers and tutors, and in work those people are your managers and colleagues. Everyone’s there to help, your lecturers and tutors in particular.

One last tip in this regard: not every conversation has to be about work. This comes back to the idea of taking a step back every now and then. Remember to make time for yourself, and the people around you. I’m willing to guarantee good results.

End of the line kids. Photo by Frederick Tubiermont on Unsplash

Finishing up

Hopefully you find some of the above helpful. I could write a big long list of all the things that I’ve learned in my time at FreeAgent, but I wanted to take the opportunity to cover some things you don’t see all that often. 

For the sake of completeness though, here are some technical suggestions: learn version control; write tests; try web-dev; git commit titles are 50 characters, and every line after is 72; just pick an editor theme, it really doesn’t matter that much.

I’ve had a blast at FreeAgent, hope to see you all again!