From b49e4c9f28c3fd2c89930c0cd7af8836d75ec2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Sch=C3=A4rtl?= <andreas@schaertl.me> Date: Thu, 21 May 2020 14:44:36 +0200 Subject: [PATCH] uloapi: GraphDB: improve error handling --- .../info/mathhub/uloapi/query/GraphDB.java | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) 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 0214feb..055c86d 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; } } -- GitLab