.NET Exceptions – RegexMatchTimeoutException

Making our way through our detailed .NET Exception Handling series, we next come to the RegexMatchTimeoutException. This exception is thrown when performing RegexMatchTimeoutException.Match() or RegexMatchTimeoutException.IsMatch() calls in which the specified timeout duration is exceeded while performing the regex operation. Let’s jump right in!

The Technical Rundown

All .NET exceptions are derived classes of the System.Exception base class, or derived from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

There’s nothing particularly complicated about the RegexMatchTimeoutException — just about every developer has used regular expressions during his or her time spent coding, as they can be a great tool when working with relatively small strings of text. However, there’s nothing inherently stopping a developer from writing code that attempts to perform regex functions on an excessively large string. If this occurs, it could very well lead to application bottlenecks, high resource costs, or, in the worst case, crashes and exceptions.

For this reason, some of the core .NET Framework regular expression methods include signatures that accept a TimeSpan argument. If provided, this value indicates how long the method should be allowed to run and process before it automatically fails. In this timeout period is exceeded, a RegexMatchTimeoutException is thrown to indicate that something has gone wrong. This ensures that there aren’t any unforeseen lockups or overuse of resources when performing most regular expression logic.

To see this in action, our sample code is quite basic. Our primary function is RegexMatchTimeoutExceptionTest(string input, string pattern, TimeSpan timeout, RegexOptions options = RegexOptions.IgnoreCase):

Nothing fancy going on here at all. We start by outputting some basic information about the regex match that is about to take place, then we execute the RegexMatchTimeoutException.Match() method with our passed parameters. If successful, the matching value is then output to the log.

Now we can test this out in the Program.Main() method:

Our input string merely contains the letter a, repeated the specified number of times. Our regex pattern of (a)+ simply tries to find the letter a, sequentially repeated as many times as possible.

We begin with a few checks using a timeout duration of only 100 nanoseconds. The results are as follows:

Executing our regex for an input string that is merely one character long is no problem, but trying to do so for a thousand-character string proves to be too much to accomplish in under 100 nanoseconds, so a RegexMatchTimeoutException is thrown.

That’s a pretty short timeout, so let’s bump it up to a full second and try again, increasing the length of our input string each time:

Unsurprisingly, modern computers are fast, so my system has no trouble performing this regex function on strings up to one million characters long. However, at one billion characters in length, rather than a RegexMatchTimeoutException, I actually get a System.OutOfMemoryException. Obviously, with enough memory and processing power, we could raise these length and timeout limitations over and over, until eventually we run into a RegexMatchTimeoutException once again, but in my case, turns out memory is the real bottleneck. Interesting!

There’s one last caveat to mention here. If you run into a situation where you absolutely must ensure that an expensive regular expression method call continues processing indefinitely, without potentially timing out, you can use the InfiniteMatchTimeout constant. Just pass that constant to any invocation of a regex match method that expects a timeout parameter, and the call will never timeout: RegexMatchTimeoutExceptionTest(new string('a', 1_000_000), "(a)+", Regex.InfiniteMatchTimeout)

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.