Where to declaring you Exceptions in a Clean Architecture

5,619 views
Skip to first unread message

Miguel Lavigne

unread,
Nov 14, 2014, 10:41:13 AM11/14/14
to clean-code...@googlegroups.com
Hi everyone,

I've been developing a project at work and applying a clean architecture approach.  I'm trying to keep my different layers in separate components.  I find that it helps understand where things are.  I've got my project decoupled in 3 major components right now.

Presentation component (presentation logic)
Data component (data access / gateway here)
Domain component  (interactors here)

In this setup the Domain component doesn't depend on anything.  It declares interfaces which are implemented by the Data component.  Therefore the Data component and the Presentation component depends on the Domain component.

The issue I'm having is with declaring my Exceptions.  I'm not sure if I'm even doing this right but there's cases where I'd like my Interactors to catch exceptions and take appropriate actions.  But those Exceptions would be specific to the Data component such as VoiceServiceUnavailableException.  How do I declare those exception in the Data component without having my Domain component depend on it?

Based on the Clean Architecture diagram found here http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html, dependencies goes inward.  Therefore how does one handle exception from an outside layer without depending about the outside layer?  

I'm very familiar with Inversion of Control and I apply it in the Domain component to make sure that this component doesn't have any dependencies on other components.  But because it's the one declaring the interfaces and the implementations are found in the Data component, should it also be the one to declare the exceptions its expecting to receive from those interfaces?  Seems kinda odd to me or perhaps it makes perfect sense, I'm not sure.

I feel like I might be missing something important here.

Andrew O'Neill

unread,
Nov 14, 2014, 4:27:04 PM11/14/14
to clean-code...@googlegroups.com
Hey,

I'm still a little new to clean architecture myself, but I think you are on the right track. What if you defined a set of general exceptions that the Interactors might expect to encounter regardless of the Data Component implementation? At the Data Component level, you can have your custom exceptions implement your Interactor exception interfaces, or you can catch lower level exceptions and wrap them with your Interactor exceptions.

This would invert the exception dependencies as desired and keep your Interactors nice and flexible. :)

Thanks,
Andrew

Jakob Holderbaum

unread,
Nov 15, 2014, 4:29:09 AM11/15/14
to clean-code...@googlegroups.com
Hey,

nice question, nice answer. I remember struggling with this exact
problem and I would have given the exact answer. But since this has
already adequately be done by Andrew, I'll just emphasize his point :)

Construct abstract domain related exceptions in your core, and throw and
catch them in your depending layers. And if you throw internal
implementation specific exceptions make sure to catch them internally
and rethrow the abstract semantic equivalent.

Cheers and a nice weekend to ya'll!
--
Jakob Holderbaum, M.Sc.
Systems Engineer

0176 637 297 71
http://jakob.io/
http://jakob.io/mentoring/
h...@jakob.io
@hldrbm

Miguel Lavigne

unread,
Nov 15, 2014, 9:54:17 AM11/15/14
to clean-code...@googlegroups.com
This is what I started doing and at first it felt a bit odd but the more I did it the more it seemed right. When you think about it the Clean Architecture is all about inverting the dependency flow so it's only right that the Exceptions would have to follow that convention as well.

Thanks Andrew for confirming my suspicions and Jacob for emphasizing on this.

Now I know I'm on the right track.

Frederik Krautwald

unread,
Nov 15, 2014, 12:01:58 PM11/15/14
to clean-code...@googlegroups.com
Whatever exceptions your domain might throw, you should catch them before they exit your application to prevent domain knowledge leaking. You then decide on how to handle them, e.g., throwing a new client-specific exception or sending some other message, all according to the architectural patterns you employ. So, you catch the domain exceptions, but it is entirely up the client on the outside how to handle your application interactor/service exceptions in the adapters it implements.

In the case of handling exceptions thrown by an outside service, such as exceptions from the data side, your adapters on that side should handle these. That way, your application wont have any knowledge of exceptions thrown by an outside service.

I hope it makes sense. Have a look here at Cockburns description of Ports and Adapters a.k.a Hexagonal Pattern.

Miguel Lavigne

unread,
Nov 17, 2014, 12:34:35 PM11/17/14
to clean-code...@googlegroups.com
It does make sense, thanks for the link.

vivek poddar

unread,
Nov 17, 2014, 2:18:02 PM11/17/14
to clean-code...@googlegroups.com
Sry for chiming in but it seems an important issue in the architecture so can anyone put up a simple example of the use case discussed above?

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.

Frederik Krautwald

unread,
Nov 17, 2014, 2:56:37 PM11/17/14
to clean-code...@googlegroups.com
Trying to be language agnostic, here’s how I’d go about doing it.

public interface DomainComponent {
   
...
   
public void someDomainComponentMethod() throws DomainComponentException;
   
...
}

public class DataComponent implements DomainComponent {
   
...
   
public void
someDomainComponentMethod() throws DomainComponentException {
       
try {
           
...
       
} catch ( DataComponentException dataComponentException ) {
           
throw new DomainComponentException();
       
}
   
}
   
...
}

public class PresentationComponent {
   
...
   
public void somePresentationComponentMethod() {
       
...
       
try {
           
DomainComponent domainComponent = new DomainComponent();
            domainComponent
->
someDomainComponentMethod();
       
} catch ( DomainComponentException domainComponentException ) {
           
...
       
}
   
}
   
...
}

DomainComponentException is declared in the “domain layer”, while DataComponentException is declared in the “data access layer”. I put the layers in quotation marks, as I don’t really regard them as layers in the view of ports and adapters.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.

Frederik Krautwald

unread,
Nov 17, 2014, 3:00:10 PM11/17/14
to clean-code...@googlegroups.com
Of course there is an obvious error. The presentation component cannot instantiate the interface DomainComponent, so that should be some implementation instead. This is simplified code for illustration purposes only!
Reply all
Reply to author
Forward
0 new messages