{"id":408,"date":"2014-03-22T15:38:15","date_gmt":"2014-03-22T14:38:15","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=408"},"modified":"2014-04-28T14:07:44","modified_gmt":"2014-04-28T13:07:44","slug":"checked-exceptions-and-streams","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/","title":{"rendered":"Checked Exceptions and Streams"},"content":{"rendered":"<p class=\"lead\">There are different viewpoints on how to use exceptions effectively in Java. Some people like checked exceptions, some argue they are a failed experiment and prefer exclusive use of unchecked exceptions. Others eschew exceptions entirely in favour of passing and returning types like <a href=\"http:\/\/download.java.net\/jdk8\/docs\/api\/java\/util\/Optional.html\">Optional<\/a> or Maybe.<\/p>\n<p>Whatever your view, you are likely to need to interact with libraries written by people with a different usage of Exceptions. This often leads to ugly code to translate failure conditions into your preferred approach. <\/p>\n<p>This is likely to become more of a pain with Java 8, where the <a href=\"http:\/\/download.java.net\/jdk8\/docs\/api\/java\/util\/stream\/Stream.html\">Streams api<\/a> doesn&#8217;t play very nicely with methods that throw exceptions.<\/p>\n<p>Fortunately, Java 8 also helps us translate between styles of exception usage more easily.<\/p>\n<h3>Using Streams with Exceptions<\/h3>\n<p>Using the streams api can become painful when you wish to use methods that throw exceptions as maps or filters.<\/p>\n<p>Take this example. What happens if Example.duplicatesShortStrings throws a checked exception? It will fail to compile. <\/p>\n<p>The map method on the stream interface expects a Function that takes an argument and returns a value without any exceptions in its method signature. <\/p>\n<p>If map did accept functions that can throw exceptions then the whole chain of transformations would fail if that exception were thrown on any given element. In this example the string &#8220;booooo&#8221; is too long and will cause an exception, which means we wouldn&#8217;t get any results at all.<\/p>\n<pre lang=\"java\">\r\nasList(\"foo\", \"bar\", \"baz\", \"booooo\")\r\n    .stream()\r\n    .map(Example::duplicatesShortStrings) \/\/ This will fail to compile \r\n    .collect(Collectors.toList());\r\n    \r\n...\r\n\r\nString duplicatesShortStrings(String input) throws InputTooLongException {\r\n    if (input.length() > 3) throw new InputTooLongException();\r\n<\/pre>\n<p>How can we handle this kind of scenario better? In functional languages you might return either the result or an error from a function rather than having exceptions. The method from the example above might look more like.<\/p>\n<pre lang=\"java\">\r\nResult<String, InputTooLong> duplicatesShortStrings(String input)\r\n<\/pre>\n<p>That&#8217;s all very well, and easier to work with, but we are likely to be consuming lots of existing code using exceptions which we are not able to re-write. <\/p>\n<p>You&#8217;ll also notice that there both of these are basically equivalent<\/p>\n<pre lang=\"java\">\r\nResult<String, InputTooLong> duplicatesShortStrings(String input)\r\nString duplicatesShortStrings(String input) throws InputTooLong\r\n<\/pre>\n<p>What if we provide a way to translate both ways between these two styles. Then we could use streams without problems. It&#8217;s mostly possible to do this. Unfortunately, we can&#8217;t record all the possible failure conditions with generics due to lack of varargs for generic type parameters. We can, however, achieve the following.<\/p>\n<pre lang=\"java\">\r\nList<String> result =\r\n    asList(\"foo\", \"bar\", \"baz\", \"boooo\")\r\n        .stream()\r\n        .map(Result.wrapReturn(Example::duplicatesShortStrings))\r\n        .map(Result.wrap(s -> s.toUpperCase()))\r\n        .filter(Result::success)\r\n        .map(Result::unwrap)\r\n        .collect(Collectors.toList());\r\n\r\nassertEquals(asList(\"FOOFOO\",\"BARBAR\",\"BAZBAZ\"), result);\r\n<\/pre>\n<p>Here we convert our method that throws an exception into a function that returns a Result type that encodes whether it is a success or failure and the type of failure. We can then continue to chain operations using the streams api, but as the stream is now a Stream&lt;Result&lt;String&gt;&gt; rather than a Stream&lt;String&gt; we need to wrap any functions that normally operate on Strings to operate on a Result&lt;String&gt; instead.<\/p>\n<p>After we&#8217;ve finished we can filter out items that did not result in an error. We also have the option of handling the errors if we wished, e.g. to provide a default value. <\/p>\n<p>Here we substitute the default &#8220;OhNoes&#8221; value for any entries in the stream for which a stream operation has resulted in an InputTooLongException.<\/p>\n<pre lang=\"java\">\r\nString result = asList(\"foo\", \"bar\", \"baz\", \"boooo\")\r\n    .stream()\r\n    .map(Result.wrapReturn(Example::duplicatesShortStrings))\r\n    .map(\r\n        Result.onSuccess((String s) -> s.toUpperCase())\r\n              .on(InputTooLongException.class, s -> \"OhNoes\")\r\n              .mapper()\r\n    )\r\n    .filter(Result::success)\r\n    .map(Result::unwrap)\r\n    .collect(Collectors.toList());\r\n\r\nassertEquals(asList(\"FOOFOO\",\"BARBAR\",\"BAZBAZ\", \"OhNoes\"), result);\r\n<\/pre>\n<p>To implement this we need a Result type that wraps our actual result, with two implementations &#8211; Success and Failure. Success taking a value and Failure taking an Exception<\/p>\n<pre lang=\"java\">\r\npublic interface Result<T> { ... }\r\nclass Success<T> implements Result<T> { ... }\r\nclass Failure<T> implements Result<T> { ... }\r\n<\/pre>\n<p>We then just need to provide a helper function that transforms a method that throws an Exception into a function that returns a Result.<\/p>\n<pre lang=\"java\">\r\npublic static <T, R, E extends Exception> \r\n    Function<T,Result<R>> wrapReturn(ExceptionalFunction<T,R,E> f) {\r\n        return t -> {\r\n            try {\r\n                return new Success<R>(f.apply(t));\r\n            } catch (Exception e) {\r\n                return new Failure<R>(e);\r\n            }\r\n        };\r\n    }\r\n<\/pre>\n<p>and a function that transforms a function that operates on unwrapped types and changes it to operate on wrapped types (for the middle of the stream)<\/p>\n<pre lang=\"java\">\r\npublic static <T, R> Function<Result<T>,Result<R>> wrap(Function<T,R> f) {\r\n    return t -> {\r\n        try {\r\n            return t.map(f);\r\n        } catch (Exception e) {\r\n            return new Failure<R>(e);\r\n        }\r\n    };\r\n}\r\n<\/pre>\n<h3>Exception Handling Patterns<\/h3>\n<p>There are also a couple of very common exception handling patterns which we can make more concise. <\/p>\n<h4>Everything unchecked<\/h4>\n<p>This approach involves wrapping all checked exceptions in runtime exceptions. This can be useful in the case where we don&#8217;t have a good way to handle the checked exceptions thrown by code we are calling, nor is it important for anything higher up the callstack to handle them. It is also useful if you don&#8217;t wish to use checked exceptions at all.<\/p>\n<p>Normally this would look something like<\/p>\n<pre lang=\"java\">\r\ntry {\r\n    String foo = Example.methodThatThrowsCheckedException(THROW);\r\n} catch (ACheckedExceptionIDontHaveAGoodWayToDealWith e) {\r\n    throw new RuntimeException(e);\r\n}\r\n<\/pre>\n<p>Now we can pull that out to a method that accepts a function and have something likely<\/p>\n<pre lang=\"java\">\r\n@Test(expected = RuntimeException.class)\r\npublic void checked_to_unchecked_should_wrap_in_runtime_exception() {\r\n    String foo = unchecked(() -> Example.methodThatThrowsCheckedException(THROW));\r\n}\r\n<\/pre>\n<p>where unchecked looks something like the following (similar implementation for void methods)<\/p>\n<pre lang=\"java\">\r\npublic interface ExceptionalSupplier<T> {\r\n    T supply() throws Exception;\r\n}\r\n\r\npublic static <T> T unchecked(ExceptionalSupplier<T> supplier) {\r\n    try {\r\n        return supplier.supply();\r\n    } catch (Error | RuntimeException rex) {\r\n        throw rex;\r\n    } catch (Exception e) {\r\n        throw new RuntimeException(e);\r\n    }\r\n}\r\n<\/pre>\n<h4>Wrapping in domain specific exception<\/h4>\n<p>Another common pattern is catching all exceptions that may occur at a lower layer in the application and wrapping them in a more meaningful exception to consumers of your code.<\/p>\n<p>This used to look like this<\/p>\n<pre lang=\"java\">\r\ntry {\r\n    return Example.methodThatThrowsCheckedException(THROW);\r\n} catch (ACheckedExceptionIDontHaveAGoodWayToDealWith e) {\r\n    throw new Wrapped(e);\r\n}\r\n<\/pre>\n<p>Again we can do the same and provide something like this, where we provide a reference to the constructor of the exception that we want to wrap exceptions in. Our wrapChecked method can now construct and throw the Wrapped exception.<\/p>\n<pre lang=\"java\">\r\n@Test(expected = Wrapped.class)\r\npublic void wrapping_checked() throws Wrapped {\r\n    wrappingChecked(() -> Example.methodThatThrowsCheckedException(THROW)).in(Wrapped::new);\r\n}\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/benjiman\/expressions\/blob\/master\/src\/main\/java\/uk\/co\/benjiweber\/expressions\/exceptions\/Result.java\">Implementation<\/a> and <a href=\"https:\/\/github.com\/benjiman\/expressions\/blob\/master\/src\/test\/java\/uk\/co\/benjiweber\/expressions\/exceptions\/ExceptionsTest.java\">examples<\/a> are on github as usual<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are different viewpoints on how to use exceptions effectively in Java. Some people like checked exceptions, some argue they are a failed experiment and prefer exclusive use of unchecked exceptions. Others eschew exceptions entirely in favour of passing and returning types like Optional or Maybe. Whatever your view, you are likely to need to&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/\" class=\"more-link\" title=\"Read Checked Exceptions and Streams\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Checked Exceptions and Streams - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"There are different viewpoints on how to use exceptions effectively in Java. Some people like checked exceptions, some argue they are a failed experiment and prefer exclusive use of unchecked exceptions. Others eschew exceptions entirely in favour of passing and returning types like Optional or Maybe. Whatever your view, you are likely to need to... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-03-22T14:38:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-04-28T13:07:44+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/\",\"name\":\"Benji&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/benjiweber.co.uk\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/\",\"name\":\"Checked Exceptions and Streams - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"datePublished\":\"2014-03-22T14:38:15+00:00\",\"dateModified\":\"2014-04-28T13:07:44+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2014\/03\/22\/checked-exceptions-and-streams\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\",\"name\":\"benji\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05fb47b31a0b329e1b790074a9b624ef?s=96&d=mm&r=g\",\"caption\":\"benji\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/408"}],"collection":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=408"}],"version-history":[{"count":22,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/408\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/408\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}