OneTrueError is an open source error handling service. It includes the context information that you forgot to include when you logged/reported the exception.
Introduction
This article is from an usage perspective. It will guide you trough all the features and show how you can get started with your own application. Another article will be posted in a week which will describe the architecture and how you can extend the server.
OneTrueError is an open source service used to detect and analyze exceptions. It works over unstable network connections and even behind corporate proxies. It attaches context information to each reported exception, which makes it significantly easier to identify and correct the cause of the exception.
Background
I’ve been programming for over 20 years. During that time, error management has been a recurring problem. Especially if your application is installed on an user computer. User reports tend to be sparse with not enough details to be able to reproduce the problem. You either have to make educated guesses or just do monkey testing to identify the root cause.
The worst problem is when think that you have found the cause and correct it. But later you receive a new error report for the same problem. What you have done then is to actually worsen the code base.
The de facto standard for error reporting have been logging. But you know how it is, we try to be good at logging and include enough details. But haven’t we missed that important field that would have told us why the exception was thrown?
OneTrueError is an attempt to solve these problems. It bypasses the user and reports exceptions, including relevent context information, directly to the programmers without a middle man.
Feature tour
Let’s start by going through all the features. The last chapter in the article contains a step-by-step guide to get started.
OneTrueError consists of a client (nuget packages) and a server (IIS web application). The client detects exceptions in your application, collect context information and uploads everything to the server.
Let’s create a simple console program and see what kind of bells and whistles we get.
When that code is run the exception will be uploaded to the server. When you go to your OneTrueError website you will see something like this:
The dashboard gives you an overview over all applications that have been configured in OneTrueError.
The information presented:
Name
Description
Incident
An aggregation of all reported exceptions that have been identified as the same error.
Active incidents
Incidents which have not been solved or ignored.
Report
An uploaded error report.
Users Waiting
Users that have entered their email address when they got the error page (due to an exception).
Feedback count
Number of error descriptions written by users.
Let’s click on the incident to get more information about that specific error.
Incidents
Incidents are used to group error reports together. Unlike log libraries, OneTrueError will not generate 5000 different errors if you receive the same exception 5000 times. Instead OneTrueError identifies that the received report is for the same exception as a previous report. Both reports are grouped together under an incident. ISO 20000 defines an incident as
unplanned interruption to a service, a reduction in the quality of a service or an event that has not yet impacted the service to the customer.
.. which fits well with what your user(s) experience when an exception is thrown.
The incident page contains information about a specific error. From here you can browse all reports that we’ve received for the error. I’ve run my sample application one more time get a total of two reports listed under the incident.
There are two actions that you can take on incidents:
Close incident – Mark it as solved/corrected (i.e. it should not happen again)
Ignore incident – Do not store any more reports or generate notifications for this incident
When you ignore an incident, all new reports will be thrown away. The report counter will continue to grow to allow you to see that reports are still being received. The new reports will however not be analyzed or stored.
When you close an incident you can also write a message which will be distributed to all users that are waiting on a new version. It’s all done through OneTrueError and only to users that signed up to status notifications when the exception was thrown.
Analysis
Below some of the analysis features that have been implemented in OneTrueError to date.
Tags
If you look at the screen shot above you’ll notice the console-application tag. OneTrueError identifies a number of StackOverflow tags for incoming reports. If you click on a tag you’ll be directed to a search for the exception message filtered for that tag only.
Error origins
Error origins shows where error reports are received from. The information is presented as a heat map. Thus you can easily identify if the error is more frequently occuring in a certain region. That indicates that the error is related to localization or cultural issues.
Context data
The context data under the incident is a combination of aggregation and specialization. Collections are first specialized, for instance the web browser “User-Agent” string is extracted to it’s own collection. Once done the
information is aggregated and then compared. OneTrueError can therefore tell you for instance if 99% of the error reports for an incident is for the culture “sv-SE”, or if there was less then 100Mb memory available in the operating system for all reports.
Feedback / Error descriptions
OneTrueError provides a way for users to leave an error description when an exception is caught. i.e. they can describe what they did when the exception occurred. They can also leave their email address to get a notification when the incident is closed.
The manual way to leave feedback is to do something like this:
Once uploaded the feedback will be available under the incident:
The more feedback your users provide, the easier to identify and correct the issue.
Error reports
Incidents are a great way to get an overview of which different errors your application have, including information like how often they occur and what they have in common. However, it’s sometimes better to get into the details of each specific error report to understand why the exception was thrown.
Therefore you can click of any of the reports in the list under the incident to take a peek.
Notifications
Ever wanted to get informed directly when an exception is thrown in your application?
OneTrueError supports multiple types of notifications. You can either get a text to your cell phone or an email message.
These are the notifications that OTE supports:
Client libraries
A client library is used to report exceptions. The library can either do it fully automated by injecting itself into your favorite library/framework’s pipeline, or by invocations made by you.
The libraries that we have built so far is:
Name
Description
OneTrueError.client
Our reporting library, allows you to manually report exceptions.
OneTrueError.client.aspnet
Generic ASP.NET library. Catches all unhandled exceptions and report them. Collects information about the HTTP request, session data etc. Allows you to easily create custom error pages for different HTTP error codes.
OneTrueError.client.mvc5
ASP.NET MVC5 specific library. Does the same as the ASP.NET library, but do also collect specific MVC5 information like route data, ViewBag etc. Also allows you to customize your error pages by just creating razor views in the error view folder.
OneTrueError.client.wcf
Catches unhandled exceptions in the WCF pipeline. Collects WCF specific information like the inbound WCF message that failed to be processed.
OneTrueError.client.log4net
Reports all exceptions that you log, including the error message that you wrote.
OneTrueError.client.winforms
Reports all unhandled exceptions. Can take screen shots and collect the state of all open forms.
It’s also possible to report exceptions directly by your own library/application. The client specification (HTTP/JSON) is available in the online documentation.
Core library
This library is the foundation of all exception reporting done with OneTrueError. All other client libraries are based upon this one.
With the core library you have to report exceptions manually like this:
You can also attach different kinds of context information which we’ll get back to in the ‘Getting started’ chapter.
Context collections
A context collection is a set of properties which is fetched from a specific source. A context collection can be HTTP Headers, a view model, Route data etc.
There are few built in context collections in the core library. Some are added to the pipeline per default, which means that they are included every time an exception is reported. Other collections require that you to add them manually when configuring the client library.
If you like, you can also create and include your own easily.
Application information
This collection includes information about your process. It contains information like used memory, thread count and amount of used CPU.
Assemblies
All assemblies that have been loaded into the AppDomain and their versions.
Exception information
Information from the exception, including all properties. If you have ever used EntityFramework and got the DbEntityValidationException? It’s exception message just says:
System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details
Since OneTrueError includes all properties, you get the validation information directly. Much better then just getting exception.ToString() in a log file, huh?
File versions
File versions for all assemblies, as the assembly version might be the same while the file version is higher (GAC hell anyone?).
Operating system
Operating system information.
Does the error happen on all windows editions or just some of them?
System information
System information.
Is the amount of available RAM memory a show stopper?
Thread information
Thread information like current UI culture.
Which thread crashed? Hint: Name threads if you start them yourself.
ASP.NET
This library is intended for ASP.NET projects which are not using MVC. So it works great for libraries based on ASP.NET such as Nancy.
Context collections
These collections are generated by the ASP.NET library.
HTTP headers
All HTTP headers for the request that failed.
Uploaded files
Name, size and context type of all files that was uploaded in the request.
Form
All items in the HTTP form (name and value).
QueryString
Query string variables (key and value).
Session
All session items (support for complex objects).
Error pages
The library contains a custom error page which can be activated (and shown) when an exception is caught.
To activate it add the following code:
The code says that the library should look after error pages (either .aspx or .html) in the specified folder:
The library tries to find pages based on the HTTP code. If the code is 404 the library tries to find the following error pages:
FileNotFound.aspx
FileNotFound.html
Error.aspx
Error.html
That is, it tries to find the most specific file first. If a specific file do not exist it tries to load a generic one.
Error information
To get information into your view, simply declare one of the following properties in your code behind.
Property
Type
Description
ErrorContext
HttpErrorReporterContext
Look in the Client API specification for more information
Exception
Exception
The caught exception
Example
Then simply display the error information in your HTML:
If you are just using HTML you can use the following template strings:
Template text
Description
$ExceptionMessage
Exception message
$reportId$
Generated report id
$URL$
OneTrueErrors own url to submit error description, email etc.
$AllowReportUploading$
If you want to allow the user to decide whether the report should be uploaded
Example:
ASP.NET MVC
This client library will provide both ASP.NET and MVC specific context information for OneTrueError.
Apart from detecting and uploading uncaught exceptions the library also provide the following features.
Error pages
The library have build in support for error pages.
To use the ones included in the library, add the following in global.asax (after the OneTrue.Configuration.Credentials() line):
Custom error pages
If our built in pages are not preferable you can include your own views.
Example
Views should be named as the HTTP codes are defined in the HttpStatusCode enum in .NET and be placed in the Views/Errors folder.
The Error.cshtml view is displayed if no other view matches.
ErrorController
If it’s not enough to control the error handling through views only you can create your own ErrorController.
Create it like any other controller in the Controllers folder.
The action methods should be named like the views. i.e. public ActionResult InternalServer().
The information provided by OneTrueError is represented as OneTrueViewModel. Take it as a parameter to your action methods.
Sample
Custom formats
An error object will be returned if XML or JSON is requested by the HTTP client. Great for ASP.NET WebApi.
json
xml
Context collections
The following collections are provided by the ASP.NET MVC library.
Controller
The controller name is collected.
Example
RouteData
Information about the route that MVC took is collected.
Example
TempData
TempData is collected if set.
Example
Result
ViewData / ViewBag
The Viewbag and/or ViewData is collected if specified.
Example
Result
log4net client
The log4net library injects OneTrueError into the logging pipeline of log4net. Each time you log something and include an exception it will be reported to OneTrueError. This is by far the easiest way to use the power of OneTrueError in legacy applications (which use log4net).
Usage
If you have code like this:
.. the exception will be picked up in OneTrueError.
As a bonus you will also see information about the log entry in OneTrueError:
Winforms
The WinForms client library can help you display error pages and collect information about the open forms.
Error pages
An error page is displayed when an exception is detected. It looks like this per default:
You configure it by using the following properties:
Examples:
Context information
WinForms have two built in context collections.
OpenForms
OneTrueError collects information from all open forms using reflection.
The information includes all controls and their configuration (position, content, visibility etc)
Let’s say that you got this form open:
.
..then you will get this information:
Screenshots
Screnshots can be activated by one of the following configuration lines:
The context collection will be shown as:
The OneTrueError pipeline
Here is a small diagram showing what steps OneTrueError takes to make sure that your exceptions are detected, caught, wrapped with context information and finally uploaded to the service for analysis.
It also identifies significant method calls if you would like to browse the code and get a hang of how things work together. Tip: Right-click in Visual Studio on the code line and use “Find usages” / “Find references” to see where the method call comes from.
Full size image
Getting started
A guide to help you report the first error.
Server installation
You can either download the source code for the server, compile and install it, or use the precompiled version. Either way the installation is a xcopy deployment.
Download or compile
Copy the binaries to a new webserver folder, typically c:\inetpub\wwwroot\onetrueerror
Go to IIS and use the context menu choice “Add application..” or “Add website..”
Name it “OneTrueError” and point on the folder that you created.
Create a database in your SQL server and modify the connection string in web.config.
Browse to the website (using your web browser)
Follow the setup wizard
One the wizard is completed, change the appKey Configured to true in web.config.
The server is now installed.
Getting the appKey/sharedsecret
To be able to report exceptions you need an appKey and a sharedSecret. The first one is used to identify which application the error report is for, the latter is used to sign all uploaded reports.
These can be found under the application that you create from the top menu in OneTrueError.
Once you’ve created an application you can find the appKey and the sharedSecret in the right side panel:
If you prefer, click on the help icon and you get a copy/paste ready instruction:
Configuring
The first thing you need to do is to tell where the uploads should be sent and which application the reports are for.
The URL should point on your local server installation.
The easiest way to report an exception is like this:
The exception should appear in your server installation shortly after being reported.
Attaching context information
Usually an exception is not enough information alone to be able to understand why the exception was thrown. OneTrueError will
always collect a large number of parameters for you. You might however have information that directly allows you to understand
why the exception was thrown.
That information can be attached when reporting:
Using anonymous object
If you need to attach multiple values you can use an anonymous object:
Result
Custom collections
We also have an object extension method which can transform any object into a context collection (one of the groups in the “Context Data” menu in our web site).
Below we are using the .ToContextCollection() extension method.
Result
Hence you can easily attach and group your information just as you like.
Categorize exceptions using tags
We automatically identify common StackOverflow.com tags when analyzing exceptions (to help you find answers by searching StackOverflow.com). You can
also add your own tags by adding a special property, named “OneTrueTags”, to any context collection:
Result:
More information
Visit the online documentation for information about everything from guides to API references.
Download the server to try the service.
Browse the source code
.. or just follow us on twitter to get updates.