Throw exception at me!

I’ve been recently drawn twice into an open discussion on when to throw exception in application’s logic.
I’ve had my opinions, others have theirs but what lead me to this post is that such fundamental topic is extremely opinionated, even among same language/environment developers.
In next few paragraphs I’ll try to sum up major proposed approaches of using exceptions (both those which abuse them and those which antagonize them).
Examples will assume that you are not using models as property bags but you actually have logic in them (vide DDD). Having that in mind, we’ll skip the fact that most probably, user receives ‘first-line’ validation of inputs on the UI.

To simplify, let’s impersonate two popular approaches with two fictional developers: 💂 Cpt. Exception (throw exception carelessly) and 👑 King Status (rarely throw exception or not even at all; loves messages, statuses and enums as responses).

Let’s play around with few cases and think what might be right or wrong with each approach.

Use case: File access (and other I/O)

This is a common case when Cpt. Exception and King Status rarely disagree.
Whenever there is a problem on attempt to access file, that we do not have prior knowledge of (or its cheaper to throw), we just throw exception:

The good:
  • We mostly do not have further info with which we could work with – in most languages and libraries its rather a system exception/error that we can just handle for user and that’s all – exception as a way to go

We could’ve of course somehow translated exceptions to some status codes or responses but there is no reason of doing so in such case.

Use case: Change object property with restrictions

Let’s take a look on simple business case. We have a Product domain model (in DDD-like sense) that has a price. Price can be changed be user that is managing shop, but let’s put permissions for actions aside as they belong to application layer logic, rather than business logic.
Price of a product cannot be changed below certain level. Let’s assume it’s a level of profitability but it can be any other value that makes sense for business.
It cannot also change if product is no longer sold. It might be a policy of a company (archived products and so on) or just a simple requirement that it doesn’t make sense for users.

What would Cpt. Exception do? Probably throw exception on each case:

The good:
  • We throw exception when core business rule (price > level of profitability) is broken
  • We enforce change caller (probably application root) to react to an exception; there at least need to be some try-catch clause
The bad:
  • Exceptions are generally costly as opposed to some internal messages
  • We also throw on non-core business rule (cannot change if is no longer sold)
  • Commonly known pattern, know as try-catch-do_nothing can lead to exception being meaningless


What would King Status do? Introduce some sort of return enum or response to notify user with:

The good:
  • No overhead when compared to throwing an exception
  • Easier to deal with if you want to work with status of change somewhere else, not only deal with invalid change
  • If combined into some sort of response, can also store some sort of message what happened, similar to exception etc.
The bad:
  • Operation must always return some sort of status or response, even if everything went fine
  • Can be much more easily ommited (on purpose or by mistake) because most of languages do not enforce usage of values returned by methods, as opposed to try-catch when you throw exception
  • (minor issue) Makes validation break some languages features – for example we cannot return from C# property, therefore we need to change to plain old methods
Verdict?

I would generally mix up two approaches and throw on broken core business rule only while giving some sort of status (or even boolean return value) for non-core validations.
I like exception approach but I can see status/response pluses too.

Use case: Return entity of given identity

Let’s imagine two queries on our persistence layer, that we want to provide us with: category of given id and products from category of given id.


Cpt. Exception would do something like this I suppose:

Plain, good, old exceptions eh?
I can see at least one place when we could remove exception with no logic change at all.

Let’s take a look on status/response King Status came up with before pointing that out:

Uh, those statuses and responses all around again?
Feels quite ugly eventually, doesn’t it?
Also we need to keep in track with all those statuses that will come up, for all the flows of operation out there (or at least errors + default).

But! We can once again mix things up and try to leverage common sense with something like this:

We could also refine it further and return null (or empty array/collection) on second case if what we actually meant was “find products that have category of such id” instead of “find me category of that id and all of its products”.
A little difference but as always, it depends!

Drawing up conclusions

As I said, recently I’ve had some discussion on that topic, but I’ve made it to one more place to confront people opinions.
Together with other developers in Polish community, we came up with few ‘rules of a thumb’ that will make it easier to decide – to throw exception or not.

First things first

If you are joining ongoing project, find out what coding standards have been introduced and organizational decisions have been made.
Maybe you are not about to make a decision as it has been made already for you?
You can of course confront current state of things if you think it’s wrong and some thoughts below will help you out with that.
Keep in mind, that’s still my opinion, but maybe it will help you out making up your own.

When to throw exception:
  • If you cannot really do a thing with what happened – external services or I/O failure
  • If you have any missing operation preconditions (empty method parameters, empty ctor parameters etc.)
  • If you feel more like enforcing other developers working with your API to react on invalid operation/data (can be skipped by empty catch though)
  • If you do not expose exceptions to outside ‘world’, ie. your application root always handles exceptions before communicating them to outside
When not to throw exception:
  • If you’re about to throw a generic, base system exception, you’re actually better off not throwing them at all; only meaningful and understandable exceptions make sense. No one will parse your exceptions messages to find out what you meant before reporting to user.
  • If certain exception is often hit in certain place (no longer meaningful)
  • If operation is in application root and only possibility is that it will be thrown either to end user (web/desktop/mobile app) or to transport layer (web service endpoint)
  • If answering questions like “IsSomething”, “FindByPredicate” (no match); generally do not use exceptions as your business flow logic and decision branching tool
  • If you meant to return multiple different yet valid outcomes of certain operation (seriously, use responses or any other meaningful object instead)
Precautions on throwing exceptions:
  • Throwing an exception is costly. If performance is critical, try to avoid them (and move to lower level language perhaps?)
  • If something happens frequently, its not an exception (I’m duplicating this because it seems to be not so obvious to some)
  • Exceptions are not a way to communicate with user! They are meant to point places where application could perform invalid operation, based on conditions you do not expect, that later on could also lead to data with invalid state flying around. You are notified that you are meant to react on such occurence, that’s what they’re for.

And, finally…

“…throw exceptions at other developers, never at users.”

Unknown Twitter poster, 2016 (let me know if you know real author)

Quick thoughts after Daj Sie Poznac 2016 finals

So we’re past ‘Daj sie poznac 2016’ finals and I feel a lot more pumped for further activities than I thought I would be. Competition was great but the finals were even greater. The amount of positive energy and interesting, really diverse topics that were presented made me really happy that I could be part of it. Kudos to the winner of competition, Piotr Gankiewicz and his Warden. Amazing project.
As for my current developer activity in web, Graphinder will currently be on hold, yet I’ve decided to try some new stuff and write my very first JavaScript library. You’ll also see me maybe not much more frequently but definitely in much more places around the web.


More of me in web

I feel quite guilty that I did not do my best to promote Graphinder and my blog per se in recent competition, therefore you’ll see me more and more in web. I’ve decided to share more and ‘attend’ more. As for a nearby future, you’ll hear me in upcoming episode of DevReview hosted by Dariusz Pawlukiewicz @ Forever F[r]ame. I hope you’ll like it!


New project: Selectibles.js

When working with plain ASP.NET MVC I’ve found it to be pain in the ass to use libraries like Select2 and Selectize.
They were often incompatible with jQuery (which I’m not a biggest fan tbh) versions I’ve used and I needed to juggle with them around just to make things (at least) work. What’s more I felt that even when they had many options, doing stuff my way was quite… dodgy.

Therefore, here it comes. My attempt for selectable controls for web.
I’m going to start with basic functionalities that will mimic Select2 from it greater days (ie. when I had 0 problems working with it).
Then, I’ll probably move on to some other controls that would be cool to have but optional to bundle (!).
I would also like to make sure the library does not need jQuery at all. It’s about time for web to move on I guess.

If you want to follow up with the project, it will build up on GitHub:

Ajax.BeginForm on DropDownList change

Recently I’ve encountered a problem on how to perform AJAX POST with helpers provided by ASP.NET MVC 5 – Ajax.BeginForm on DropDownList change event.

Idea behind

Imagine you have ViewModel like this:

And MVC controller action like this:

My first thought was to to something like this (note I didn’t used TextBoxFor and DropdownListFor because I actually used Ajax.BeginForm to edit attributes of each item in collection of objects inside TestVM, not the TestVM attributes themselves):

However, what I kept receiving was a postback to the /Post address instead of making an AJAX call.
I’ve also added

@Scripts.Render(“~/Scripts/jquery.unobtrusive-ajax.js”)

in several places around thinking it might be rendered wrong but nothing changed.
I’ve also kept changing how, when and where is jquery and jquery-validate loaded but no luck.

Solution

In the end I gave a try something like this (kudos to one of fellow StackOverflow’ers for an answer, can’t find it at the moment):

Yes, that’s right – only change is replacing:

onchange = “this.form.submit();”

with:

onchange = “$(this.form).submit();”

With that you can easily forget about button type=”submit” and move on to more natural way of updating records with Ajax.BeginForm on DropDownList change event.