diff --git a/experimental/uloapi/src/main/java/info/mathhub/uloapi/query/GraphDB.java b/experimental/uloapi/src/main/java/info/mathhub/uloapi/query/GraphDB.java index 0214febd481f0513363f3cd15ea6d2987967bde4..055c86d57b8618c4da4ab5c1adc50a7d9cf8722c 100644 --- a/experimental/uloapi/src/main/java/info/mathhub/uloapi/query/GraphDB.java +++ b/experimental/uloapi/src/main/java/info/mathhub/uloapi/query/GraphDB.java @@ -36,6 +36,16 @@ public class GraphDB { T op(RepositoryManager manager, Repository repository, RepositoryConnection connection); } + /** + * Functional interface that defines a function that takes nothing, does something + * and returns nothing. + * + * Functional programmers hate this. + */ + private interface Procedure { + void apply() throws Exception; + } + /** * Run an operation on a remote repository. * @@ -52,6 +62,9 @@ public class GraphDB { Repository repository = null; RepositoryConnection connection = null; + Exception err = null; + T result = null; + try { manager = new RemoteRepositoryManager(serverUrl); manager.init(); @@ -61,20 +74,49 @@ public class GraphDB { } connection = repository.getConnection(); - return op.op(manager, repository, connection); + result = op.op(manager, repository, connection); + } catch (Exception e) { + err = e; } finally { if (connection != null) { - connection.close(); + err = chain(err, connection::close); } if (repository != null) { - repository.shutDown(); + err = chain(err, repository::shutDown); } if (manager != null) { - manager.shutDown(); + err = chain(err, manager::shutDown); + } + } + + if (err != null) { + throw new OperationException("execute failed", err); + } + + return result; + } + + /** + * Execute proc and return {@code e} if not {@code null}, the exception + * caused by {@code proc} or {@code null}. + * @return If {@code e} is not {@code null}, always return {@code e}. + * Otherwise, if {@code proc} caused an exception, return that exception or + * return {@code null} if {@code proc} did not cause an exception. + */ + private static Exception chain(Exception e, Procedure proc) { + Exception ret = e; + + try { + proc.apply(); + } catch (Exception ne) { + if (ret == null) { + ret = ne; } } + + return ret; } }