shawjef3 / tryutils   2.0.0

Apache License 2.0 GitHub

Adds some useful methods to collections to help with failures or closing.

Scala versions: 3.x 2.13 2.12 2.11

Tryutils

This project aims to ease operations on collections where failure should be allowed.

The main problem I wanted solved was to call close on all items of a collection, aggregating exceptions and adding them to the first one as suppressed exceptions.

Usage

Dependency

libraryDependencies += "me.jeffshaw.tryutils" %% "tryutils" % "2.0.0"

Imports

Scala

import me.jeffshaw.tryutils._

Java

import me.jeffshaw.tryutils.TryForeachException;
import me.jeffshaw.tryutils.TryIterable;

tryClose

Scala

val closeables: Seq[AutoCloseable] = null
try {
  closeables.tryClose()
} catch {
  case e: TryForeachException[AutoCloseable] =>
    // recover using `e.failures`
}

Java

final Iterable<AutoCloseable> closeables = null;
try {
  TryIterable.tryClose(closeables);
} catch (TryForeachException e) {
  // recover using `e.getFailures()`
}

tryForeach

The underlying mechanism for tryClose is tryForeach. It is the same, exception instead of calling AutoCloseable#close(), it will call a function of your choosing.

Scala

val ints: Seq[Int] = null
try {
  ints.tryForeach(i => if (i == 0) throw new Exception())
} catch {
  case e: TryForeachException[AutoCloseable] =>
  // recover using `e.failures`
}

Java

final Iterable<Object> closeables = null;
try {
  TryIterable.tryForEach(
    (Object o) -> {
      if (isInvalid(o)) {
        throw new RuntimeException();
      }
    },
    closeables);
} catch (TryForeachException e) {
  // recover using `e.getValues()`
}

There are also specialized methods for primitives.

final int[] ints = null;
try {
  TryIterable.tryForEachInt(
    (int i) -> {
      if (isInvalid(i)) {
        throw new RuntimeException();
      }
    },
    ints);
} catch (TryForeachException e) {
  // recover using `e.getFailures()`
}

Changelog

2.0.0

TryForeachException now directly ties the throwable to the value that caused it. Before you had to iterate through the cause and its suppressed exceptions.