From 592bcdef50dbb2d02ef5805608a6303a871a03eb Mon Sep 17 00:00:00 2001 From: Wu Tao Date: Mon, 4 Nov 2019 11:15:40 +0800 Subject: [PATCH] feat: add more exception info on synchronous APIs (#62) --- .../xiaomi/infra/pegasus/base/error_code.java | 1 + .../infra/pegasus/client/PException.java | 20 +++++ .../infra/pegasus/client/PegasusTable.java | 84 +++++++++---------- .../infra/pegasus/client/TestPException.java | 27 ++++++ 4 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 src/test/java/com/xiaomi/infra/pegasus/client/TestPException.java diff --git a/src/main/java/com/xiaomi/infra/pegasus/base/error_code.java b/src/main/java/com/xiaomi/infra/pegasus/base/error_code.java index f557ff6c..47f0b0ac 100644 --- a/src/main/java/com/xiaomi/infra/pegasus/base/error_code.java +++ b/src/main/java/com/xiaomi/infra/pegasus/base/error_code.java @@ -102,6 +102,7 @@ public enum error_types { // ERROR_CODE defined by client ERR_SESSION_RESET, + ERR_THREAD_INTERRUPTED, }; public error_types errno; diff --git a/src/main/java/com/xiaomi/infra/pegasus/client/PException.java b/src/main/java/com/xiaomi/infra/pegasus/client/PException.java index feec9a93..53f3d4b2 100644 --- a/src/main/java/com/xiaomi/infra/pegasus/client/PException.java +++ b/src/main/java/com/xiaomi/infra/pegasus/client/PException.java @@ -3,6 +3,10 @@ // can be found in the LICENSE file in the root directory of this source tree. package com.xiaomi.infra.pegasus.client; +import com.xiaomi.infra.pegasus.base.error_code; +import com.xiaomi.infra.pegasus.rpc.ReplicationException; +import java.util.concurrent.TimeoutException; + /** * The generic type of exception thrown by all of the Pegasus APIs. * @@ -27,4 +31,20 @@ public PException(String message) { public PException(Throwable cause) { super(cause); } + + static PException threadInterrupted(String tableName, InterruptedException e) { + return new PException( + new ReplicationException( + error_code.error_types.ERR_THREAD_INTERRUPTED, + String.format("[table=%s] Thread was interrupted: %s", tableName, e.getMessage()))); + } + + static PException timeout(String tableName, int timeout, TimeoutException e) { + return new PException( + new ReplicationException( + error_code.error_types.ERR_TIMEOUT, + String.format( + "[table=%s, timeout=%dms] Timeout on Future await: %s", + tableName, timeout, e.getMessage()))); + } } diff --git a/src/main/java/com/xiaomi/infra/pegasus/client/PegasusTable.java b/src/main/java/com/xiaomi/infra/pegasus/client/PegasusTable.java index 482f6388..7a9f8de1 100644 --- a/src/main/java/com/xiaomi/infra/pegasus/client/PegasusTable.java +++ b/src/main/java/com/xiaomi/infra/pegasus/client/PegasusTable.java @@ -862,9 +862,9 @@ public boolean exist(byte[] hashKey, byte[] sortKey, int timeout) throws PExcept try { return asyncExist(hashKey, sortKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -876,9 +876,9 @@ public long sortKeyCount(byte[] hashKey, int timeout) throws PException { try { return asyncSortKeyCount(hashKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -890,9 +890,9 @@ public byte[] get(byte[] hashKey, byte[] sortKey, int timeout) throws PException try { return asyncGet(hashKey, sortKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -969,9 +969,9 @@ public MultiGetResult multiGet( return asyncMultiGet(hashKey, sortKeys, maxFetchCount, maxFetchSize, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -984,9 +984,9 @@ public MultiGetResult multiGet(byte[] hashKey, List sortKeys, int timeou try { return asyncMultiGet(hashKey, sortKeys, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1008,9 +1008,9 @@ public MultiGetResult multiGet( hashKey, startSortKey, stopSortKey, options, maxFetchCount, maxFetchSize, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1029,9 +1029,9 @@ public MultiGetResult multiGet( return asyncMultiGet(hashKey, startSortKey, stopSortKey, options, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1112,9 +1112,9 @@ public MultiGetSortKeysResult multiGetSortKeys( return asyncMultiGetSortKeys(hashKey, maxFetchCount, maxFetchSize, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1126,9 +1126,9 @@ public MultiGetSortKeysResult multiGetSortKeys(byte[] hashKey, int timeout) thro try { return asyncMultiGetSortKeys(hashKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1141,9 +1141,9 @@ public void set(byte[] hashKey, byte[] sortKey, byte[] value, int ttlSeconds, in try { asyncSet(hashKey, sortKey, value, ttlSeconds, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1155,9 +1155,9 @@ public void set(byte[] hashKey, byte[] sortKey, byte[] value, int timeout) throw try { asyncSet(hashKey, sortKey, value, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1215,9 +1215,9 @@ public void multiSet( try { asyncMultiSet(hashKey, values, ttlSeconds, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1230,9 +1230,9 @@ public void multiSet(byte[] hashKey, List> values, int time try { asyncMultiSet(hashKey, values, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1298,9 +1298,9 @@ public void del(byte[] hashKey, byte[] sortKey, int timeout) throws PException { try { asyncDel(hashKey, sortKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1362,9 +1362,9 @@ public void multiDel(byte[] hashKey, List sortKeys, int timeout) throws try { asyncMultiDel(hashKey, sortKeys, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1517,9 +1517,9 @@ public long incr(byte[] hashKey, byte[] sortKey, long increment, int ttlSeconds, return asyncIncr(hashKey, sortKey, increment, ttlSeconds, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1531,9 +1531,9 @@ public long incr(byte[] hashKey, byte[] sortKey, long increment, int timeout) th try { return asyncIncr(hashKey, sortKey, increment, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1563,9 +1563,9 @@ public CheckAndSetResult checkAndSet( timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1587,9 +1587,9 @@ public CheckAndMutateResult checkAndMutate( hashKey, checkSortKey, checkType, checkOperand, mutations, options, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1610,9 +1610,9 @@ public CompareExchangeResult compareExchange( hashKey, sortKey, expectedValue, desiredValue, ttlSeconds, timeout) .get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } @@ -1624,9 +1624,9 @@ public int ttl(byte[] hashKey, byte[] sortKey, int timeout) throws PException { try { return asyncTTL(hashKey, sortKey, timeout).get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.threadInterrupted(table.getTableName(), e); } catch (TimeoutException e) { - throw new PException(new ReplicationException(error_code.error_types.ERR_TIMEOUT)); + throw PException.timeout(table.getTableName(), timeout, e); } catch (ExecutionException e) { throw new PException(e); } diff --git a/src/test/java/com/xiaomi/infra/pegasus/client/TestPException.java b/src/test/java/com/xiaomi/infra/pegasus/client/TestPException.java new file mode 100644 index 00000000..56b6f54c --- /dev/null +++ b/src/test/java/com/xiaomi/infra/pegasus/client/TestPException.java @@ -0,0 +1,27 @@ +// Copyright (c) 2019, Xiaomi, Inc. All rights reserved. +// This source code is licensed under the Apache License Version 2.0, which +// can be found in the LICENSE file in the root directory of this source tree. + +package com.xiaomi.infra.pegasus.client; + +import java.util.concurrent.TimeoutException; +import org.junit.Assert; +import org.junit.Test; + +public class TestPException { + @Test + public void testThreadInterrupted() throws Exception { + PException ex = PException.threadInterrupted("test", new InterruptedException("intxxx")); + Assert.assertEquals( + "com.xiaomi.infra.pegasus.rpc.ReplicationException: ERR_THREAD_INTERRUPTED: [table=test] Thread was interrupted: intxxx", + ex.getMessage()); + } + + @Test + public void testTimeout() throws Exception { + PException ex = PException.timeout("test", 1000, new TimeoutException("tmxxx")); + Assert.assertEquals( + "com.xiaomi.infra.pegasus.rpc.ReplicationException: ERR_TIMEOUT: [table=test, timeout=1000ms] Timeout on Future await: tmxxx", + ex.getMessage()); + } +}