2

I have come across a small issue while I was making a simple API for the backend code of registration and login in a website with a FIDO device.

I am basically wrapping the yubico u2f library and making it even simpler to use. The problem that I have run at is with exceptions, I want to throw from my API to the backend server the com.yubico.u2f.exceptions.NoEligableDevicesException exception but I don't want my user (the backend developer) to ever have to see or import the yubico library.

Therefore my solution was to wrap that exception like so:

package com.github.dkanellis.fikey.exceptions;

import com.yubico.u2f.data.DeviceRegistration;

public class NoEligableDevicesException extends com.yubico.u2f.exceptions.NoEligableDevicesException {
    public NoEligableDevicesException(Iterable<? extends DeviceRegistration> devices, String message, Throwable cause) {
        super(devices, message, cause);
    }

    public NoEligableDevicesException(Iterable<? extends DeviceRegistration> devices, String message) {
        super(devices, message);
    }
}

and then throw to the user my exception that wraps the yubico exception. The problem is that this add complexity to my code and everytime the com.yubico.u2f.exceptions.NoEligableDevicesException exception occurs I have to catch it and throw the com.github.dkanellis.fikey.exceptions.NoEligableDevicesException.

Is there a better way to do this?

Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
Aki K
  • 1,222
  • 1
  • 27
  • 49
  • Not that I can see. (Side note: using `com.github` as your base package is probably not a good idea unless you are actually working for GitHub.) – Sam Estep Jun 28 '15 at 13:02
  • @RedRoboHood I remember people saying to do this if you don't have a website (because basically by github profile is my website). Is there any other better conventions for people without websites? – Aki K Jun 28 '15 at 13:04
  • Without seeing your code and the level of abstraction it is hard to say. What you should do is to use internal methods which are already wrapping the exception. Then you reduce the places. This would not work if you wrap the API 1:1 (but you stated that you dont). – eckes Jun 28 '15 at 13:05
  • I don't know for sure. Does GitHub encourage this convention? – Sam Estep Jun 28 '15 at 13:05
  • @RedRoboHood if you have a xyz account on github, using com.github.xyz as a root package for your project is standard. This is not github specific. See also: http://central.sonatype.org/pages/choosing-your-coordinates.html – assylias Jun 28 '15 at 13:07
  • @assylias Ah, I wasn't aware of that. Good to know! – Sam Estep Jun 28 '15 at 13:08
  • @AkiK If your exception has the same name and content, what's the point of wrapping the original exception? – assylias Jun 28 '15 at 13:11
  • @assylias to have a backend developer have only one dependency in his project (my API and not yubico's) – Aki K Jun 28 '15 at 13:12
  • @AkiK He will have a dependency to yubico through your project (transitive dependency) - so I don't see how it makes a difference... – assylias Jun 28 '15 at 13:13
  • 1
    @assylias I believe what the OP is trying to say is that `NoEligableDevicesException` is a checked exception. If a method in the OP's library throws this exception, the user of the API will have to catch or rethrow this exception. The OP does not want the user of the API to depend on the underlying library code. If the OP chooses to use another library in the future, the user of the API continues to depend on the wrapped `Exception` classes without bothering about what library is used underneath the API. – Chetan Kinger Jun 28 '15 at 13:22

1 Answers1

2

The problem is that this add complexity to my code and everytime the com.yubico.u2f.exceptions.NoEligableDevicesException exception occurs I have to catch it and throw the com.github.dkanellis.fikey.exceptions.NoEligableDevicesException.

This is not a problem. This is actually the recommended way to propagate an Exception between different layers of your application. I had come across this excellent article on propagating an Exception recently. (It's a .Net article but still applicable for Java)

Wrapping the actual Exception into your own Exception subclass gives you the flexibility to change the underlying dependencies of your API without breaking client code. The client code continues to depend on your Exception subclass.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • @AkiK Take a look at aspect oriented program. There might be a solution for you using AOP that takes care of wrapping and throwing the exception of your choice without doing it manually in each and every method. I would have added this as part of my answer but it's not something I have tried so can't be sure if it works. – Chetan Kinger Jun 30 '15 at 09:15
  • Because for now the occurrences of the exception wrapping in my code are small I will probably keep things simple and wrap it myself but in the future where I will probably run into this more I will use AOP, this is the current code where I just have a couple of occurrences of this happening https://goo.gl/45dfHa – Aki K Jun 30 '15 at 10:10