All Projects → zalando → Faux Pas

zalando / Faux Pas

Licence: mit
A library that simplifies error handling for Functional Programming in Java

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Faux Pas

Bugsnag Js
Javascript error handling tool for Bugsnag. Monitor and report JavaScript bugs & errors.
Stars: ✭ 625 (+525%)
Mutual labels:  error-handling, monitoring, exception-handling
react-error-guard
⚛️An overlay for displaying stack frames based on create-react-app/packages/react-error-overlay
Stars: ✭ 18 (-82%)
Mutual labels:  error-handling, exception-handling
ignition-stackoverflow
An Ignition tab that fetches StackOverflow questions and provides a searchbar.
Stars: ✭ 74 (-26%)
Mutual labels:  error-handling, exception-handling
Swift Validated
🛂 A result type that accumulates multiple errors.
Stars: ✭ 350 (+250%)
Mutual labels:  error-handling, functional-programming
cakephp-error-email
ErrorEmail Plugin for CakePHP3.x
Stars: ✭ 16 (-84%)
Mutual labels:  error-handling, exception-handling
catchr
catchr: Flexible, useful tools for dealing with conditions in R, for new users and veterans
Stars: ✭ 17 (-83%)
Mutual labels:  error-handling, exception-handling
Hamsters
A mini Scala utility library
Stars: ✭ 292 (+192%)
Mutual labels:  error-handling, functional-programming
Graphql Errors
Simple error handler for GraphQL Ruby ❗️
Stars: ✭ 170 (+70%)
Mutual labels:  error-handling, exception-handling
Log Process Errors
Show some ❤️ to Node.js process errors
Stars: ✭ 424 (+324%)
Mutual labels:  error-handling, monitoring
Bugsnag Php
Bugsnag error monitoring and crash reporting tool for PHP apps
Stars: ✭ 475 (+375%)
Mutual labels:  error-handling, exception-handling
Traceback with variables
Adds variables to python traceback. Simple, lightweight, controllable. Debug reasons of exceptions by logging or pretty printing colorful variable contexts for each frame in a stacktrace, showing every value. Dump locals environments after errors to console, files, and loggers. Works in Jupyter and IPython. Install with pip or conda.
Stars: ✭ 509 (+409%)
Mutual labels:  error-handling, exception-handling
Poica
🧮 A research programming language on top of C macros
Stars: ✭ 231 (+131%)
Mutual labels:  error-handling, functional-programming
Exceptions4c
🐑 An exception handling framework for C
Stars: ✭ 189 (+89%)
Mutual labels:  error-handling, exception-handling
bugsnag-java
Bugsnag error reporting for Java.
Stars: ✭ 51 (-49%)
Mutual labels:  error-handling, exception-handling
Exceptionless
Exceptionless server and jobs
Stars: ✭ 2,107 (+2007%)
Mutual labels:  error-handling, monitoring
Throwing Function
Checked Exceptions-enabled Java 8+ functional interfaces + adapters
Stars: ✭ 279 (+179%)
Mutual labels:  exception-handling, functional-programming
Stacktracey
Parses call stacks. Reads sources. Clean & filtered output. Sourcemaps. Node & browsers.
Stars: ✭ 115 (+15%)
Mutual labels:  error-handling, exception-handling
Bugsnag React Native
Error monitoring and reporting tool for native exceptions and JS errors in React Native apps
Stars: ✭ 374 (+274%)
Mutual labels:  error-handling, exception-handling
Bash Oo Framework
Bash Infinity is a modern standard library / framework / boilerplate for Bash
Stars: ✭ 5,247 (+5147%)
Mutual labels:  error-handling, functional-programming
Mjn
⚡️Like loadash.get, but in ~200 bytes
Stars: ✭ 69 (-31%)
Mutual labels:  error-handling, exception-handling

Faux Pas: Error handling in Functional Programming

Spilled coffee

Stability: Sustained Build Status Coverage Status Code Quality Javadoc Release Maven Central License

Faux pas noun, /fəʊ pɑː/: blunder; misstep, false step

Faux Pas is a library that simplifies error handling for Functional Programming in Java. It fixes the issue that none of the functional interfaces in the Java Runtime by default is allowed to throw checked exceptions.

  • Technology stack: Java 8+, functional interfaces
  • Status: 0.x, originally ported from Riptide, used in production

Example

interface Client {
    User read(final String name) throws IOException;
}

Function<String, User> readUser = throwingFunction(client::read);
readUser.apply("Bob"); // may throw IOException directly

Features

  • Checked exceptions for functional interfaces
  • Compatible with the JDK types

Dependencies

  • Java 8 or higher
  • Lombok (no runtime dependency)

Installation

Add the following dependency to your project:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>faux-pas</artifactId>
    <version>${faux-pas.version}</version>
</dependency>

Usage

Throwing functional interfaces

Faux Pas has a variant of every major functional interface from the Java core:

The followings statements apply to each of them:

  • extends the official interface, i.e. they are 100% compatible
  • sneakily throws the original exception

Creation

The way the Java runtime implemented functional interfaces always requires additional type information, either by using a cast or a local variable:

// compiler error
client::read.apply(name);

// too verbose
((ThrowingFunction<String, User, IOException>) client::read).apply(name);

// local variable may not always be desired
ThrowingFunction<String, User, IOException> readUser = client::read;
readUser.apply(name);

As a workaround there is a static factory method for every interface type inFauxPas. All of them are called throwingRunnable, throwingSupplier and so forth. It allows for concise one-line statements:

List<User> users = names.stream()
    .map(throwingFunction(client::read))
    .collect(toList());

Try-with-resources alternative

Traditional try-with-resources statements are compiled into byte code that includes unreachable parts and unfortunately JaCoCo has no support for filtering yet. That's why we came up with an alternative implementation. The official example for the try-with-resources statement looks like this:

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

Compared to ours:

return tryWith(new BufferedReader(new FileReader(path)), br -> 
    br.readLine()
);

CompletableFuture.exceptionally(Function)

CompletableFuture.exceptionally(..) is a very powerful but often overlooked tool. It allows to inject partial exception handling into a CompletableFuture:

future.exceptionally(e -> {
    Throwable t = e instanceof CompletionException ? e.getCause() : e;

    if (t instanceof NoRouteToHostException) {
        return fallbackValueFor(e);
    }

    throw e instanceof CompletionException ? e : new CompletionException(t);
})

Unfortunately it has a contract that makes it harder to use than it needs to:

In order to use the operation correctly one needs to follow these rules:

  1. Unwrap given throwable if it's an instance of CompletionException.
  2. Wrap checked exceptions in a CompletionException before throwing.

FauxPas.partially(..) relives some of the pain by changing the interface and contract a bit to make it more usable. The following example is functionally equivalent to the one from above:

future.exceptionally(partially(e -> {
    if (e instanceof NoRouteToHostException) {
        return fallbackValueFor(e);
    }

    throw e;
}))
  1. Takes a ThrowingFunction<Throwable, T, Throwable>, i.e. it allows clients to
    • directly re-throw the throwable argument
    • throw any exception during exception handling as-is
  2. Will automatically unwrap a CompletionException before passing it to the given function. I.e. the supplied function will never have to deal with CompletionException directly. Except for the rare occasion that the CompletionException has no cause, in which case it will be passed to the given function.
  3. Will automatically wrap any thrown Exception inside a CompletionException, if needed.

The last example is actually so common, that there is an overloaded version of partially that caters for this use particular case:

future.exceptionally(partially(NoRouteToHostException.class, this::fallbackValueFor))

CompletableFuture.whenComplete(BiConsumer)

future.whenComplete(failedWith(TimeoutException.class, e -> {
    request.cancel();
}))

Other missing pieces in CompletableFuture's API are exceptionallyCompose and handleCompose. Both can be seen as a combination of exceptionally + compose and handle + compose respectively. They basically allow to supply another CompletableFuture rather than concrete values directly. This is allows for asynchronous fallbacks:

exceptionallyCompose(users.find(name), e -> archive.find(name))

Getting Help

If you have questions, concerns, bug reports, etc., please file an issue in this repository's Issue Tracker.

Getting Involved/Contributing

To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. For more details, check the contribution guidelines.

Alternatives

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].