i just thought I’d ask this here to see what sorts of opinions I’d hear from other experienced developers.
I’ve been thinking that using some sort of easily searchable error identifier (e. g. EC100) associated with each error message is a good practice. The reason it’s a good practice is that it can make it a little easier if an end-user reports an error to know what to search for in the source code. For example, if I have an error “Key not found” when I’m attempting to search a database that string might occur in a few places. But if the error string is “EC100 Key not found” it’s much easier and more precise to search for EC100 so I’m more likely to find at least the point where the error was raised.
As I say, I’m just curious about the opinions of some of the developers on this list. I can’t see a downside to this practice but if there is a drawback to it, I’d expect that folks here would be able to point it out to me.
If the error codes/msgs were public the only drawback I can think of is if something might pose a security threat.
Is this for an online app? What about logging errors instead? So whenever an error is encountered it is logged and the user is given a ref code in case they need to contact you about it (and you are emailed whenever an error is logged so you can investigate - you could also choose to mute certain errors). This is what I do on one of my apps.
Yeah the idea would be that the error messages would be public.
My observation over the years has been that when we get error reports from customers, they often start as “It doesn’t work!” When you ask for more details they can sometimes come up with the error message but often the error message will be paraphrased. That is, if we have an error message like “Key cannot be found” we’ll often get “there was something about something not being found?”
A specific error code might help to get the exact error message that the end user is seeing more easily. Of course this would also mean asking the end-users to look for the code. Something like “if you see an error, please just jot down this code number”
This isn’t really specific to a particular use case–just a practice I’ve been considering adding to apps going forward.
Could be a nice idea depending on how many of these customer feedbacks you get.
A nice touch with elixir would be a macro to generate the code like a checksum of the error text/code location and then compile a list of such errors during compilation
I didn’t really have that in mind but it’s an interesting idea. I mean I recall seeing something with the old MS C++ compiler where it’d build a map of symbols that could be used with some of their tooling so that if you get a crash dump you might be able to trace it back to a specific symbol in the code.
I can remember that for instance game console companies use error codes that are shown when something does not work. Often, this code is actually more specific than the message, but would only make sense to a developer/troubleshooter. It is a great way to ensure that you know that you and your users are tslking about the same problem.
For a web applications instead of TAG for each error a better idea would be to use a GUID for each request <-> response pair. Every time your server receives a request it would generate a GUID and use it in your logs until response. If an error occurs you are able to identify the request <-> response pair and everything inbetween.
You might present the GUID to the user or log it in the background with the unique user_id/name and collect it with tools like splunk or rollbar (btw.: rollbar has an elixir client implemented).
If you are using Phoenix such GUID is already included in each request, response pair as x-request-id
If you want to have every error that was ever encountered unique, using GUIDs is a good idea. If you only want to know what type of error was encountered, then there are simpler number generation techniques, that are also easier for clients to e.g. say over the telephone.
Again, the best solution will depend on your specific project. But I think a GUID is the wrong way to go because you want something that the end user could supply on telephone during a support call. So back to my original idea, just doing something based on:
error_code =
(message <> __ENV__.file <> __ENV_.line)
|> sha_sum
|> String.slice(-6..-1)
defp sha_sum(str) do
:crypto.hash(:sha256, str) |> Base.encode16
end
You would get a code that could easily be communicated over phone, with little probability that a code was used for many different errors.
The drawback of this solution is that it is impossible to find out on what message+filename+linenumber something crashed, unless you iterate over all message+filename+linenumbers yourself.
And of course, line numbers are something that change during even small edits to the source code.
I wonder if there is a solution that does not involve manually crafting error codes, while being easy to look up by the creator of the program.
No, my plan would be to create a macro that created the public facing error code and then stored the {file, line, message} triplet in a module list that may be ectracted after compilation
Yeah I think @danseid is possibly misunderstanding what I’m getting at. I want to give the end-users a definite number they can report when they see an error so it’s more likely that support/development can find exactly which error the end-user saw. A GUID might actually be a bit counter-productive in that regard.
I really like that idea @tallakt. Would be quite helpful in diagnosing runtime issues. But that idea (which is excellent) is more geared toward developers. My initial idea is to make it easier for end-users to report errors when they see them so that development has a better idea of where in the code to start searching.
This shows how cool elixir metaprogramming is . The user still needs to provide the correct version number of your application in case the line number of error_code changes.
It wasn’t clear to me, that phone is the only option to report. Copy&Paste GUID will work very well if email or ticket system is also a possibility.
I would like you to rethink the small part of your initial idea: “end-users to report errors”. Why should a user report errors, if your app can report it automatically in a system of your choice?
For example I was part of a team in an enterprise web project, written in JAVA . We have created an error reporter, to report in JIRA directly. So the user just saw the error message and received the same moment an email, that an issue in JIRA was created. And probably solved some day
Because that was the use case I had in mind. Any system which can be built to automatically catch and fix errors should be built to do so. But most of the time when an error occurs that get reported by an end-user it’s some unanticipated use case (e. g. the infamous “This Code Should Never Be Executed” error message). I’m considering a more general pattern to deal with error reporting when it’s something that floats to the attention of an end-user.