From aabbf37069ded28df8dea5e4c0d124c23b294616 Mon Sep 17 00:00:00 2001 From: Oleg Kuznetsov Date: Fri, 23 Jul 2021 15:06:32 +0300 Subject: [PATCH] Fix compatibility with 1.10 and fix errors parsing #89 --- .../exceptions/errors/TarantoolErrors.java | 22 ++--- .../driver/integration/TarantoolErrorsIT.java | 96 +++++++++---------- .../cartridge/app/roles/api_router.lua | 6 +- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/main/java/io/tarantool/driver/exceptions/errors/TarantoolErrors.java b/src/main/java/io/tarantool/driver/exceptions/errors/TarantoolErrors.java index 46c9e298..2d63e4e7 100644 --- a/src/main/java/io/tarantool/driver/exceptions/errors/TarantoolErrors.java +++ b/src/main/java/io/tarantool/driver/exceptions/errors/TarantoolErrors.java @@ -26,20 +26,23 @@ public class TarantoolErrors { private enum ErrorsCodes { NO_CONNECTION("77"), TIMEOUT("78"); private final String code; + ErrorsCodes(String code) { this.code = code; } + public String getCode() { return code; } } + private static final String CLIENT_ERROR = "ClientError"; /** * Produces {@link TarantoolInternalException} subclasses * from the serialized representation in the format of require('errors').new_class("NewError"), - * @see tarantool/errors * + * @see tarantool/errors */ public static class TarantoolErrorsErrorFactory implements TarantoolErrorFactory { private static final StringValue LINE = ValueFactory.newString("line"); @@ -49,12 +52,10 @@ public static class TarantoolErrorsErrorFactory implements TarantoolErrorFactory private static final StringValue ERROR_MESSAGE = ValueFactory.newString("str"); private static final StringValue STACKTRACE = ValueFactory.newString("stack"); private static final Pattern NETWORK_ERROR_PATTERN = Pattern.compile( - ".*" + - "\"code\":" + - "[" + ErrorsCodes.NO_CONNECTION.getCode() + "|" + ErrorsCodes.TIMEOUT.getCode() + "]" + - ".*" + - "\"type\":\"" + CLIENT_ERROR + "\"" + - ".*", Pattern.DOTALL); + "(?=.*\"type\":\"" + CLIENT_ERROR + "\")" + + "(?=.*\"code\":" + + "[" + ErrorsCodes.NO_CONNECTION.getCode() + "|" + ErrorsCodes.TIMEOUT.getCode() + "])", + Pattern.DOTALL); public TarantoolErrorsErrorFactory() { } @@ -67,7 +68,7 @@ public Optional create(Value error) { Map map = error.asMapValue().map(); String exceptionMessage = ""; - String errorMessage = map.containsKey(ERROR_MESSAGE) ? map.get(ERROR_MESSAGE).toString() : null; + String errorMessage = map.containsKey(ERROR_MESSAGE) ? map.get(ERROR_MESSAGE).toString() : null; String err = map.containsKey(ERR) ? map.get(ERR).toString() : null; String line = map.containsKey(LINE) ? map.get(LINE).toString() : null; String className = map.containsKey(CLASS_NAME) ? map.get(CLASS_NAME).toString() : null; @@ -133,8 +134,8 @@ private Boolean isErrorsError(String errorMessage) { /** * Produces {@link TarantoolInternalException} subclasses from the serialized representation * in the format of box.error:unpack, - * @see box_error * + * @see box_error */ public static class TarantoolBoxErrorFactory implements TarantoolErrorFactory { private static final StringValue CODE = ValueFactory.newString("code"); @@ -236,7 +237,7 @@ private Boolean isNetworkError(String code) { /** * Check the error message contains fields of code and message * - * @param code code from box.error + * @param code code from box.error * @param message string message from box.error * @return an {@link Boolean} */ @@ -249,7 +250,6 @@ private Boolean isBoxError(String code, String message) { * The factory is finalizing, i.e. errors passed into * it will always be introverted as appropriate for the given factory * The error is generated in a message that is passed to {@link TarantoolInternalException} - * */ public static class TarantoolUnrecognizedErrorFactory implements TarantoolErrorFactory { public TarantoolUnrecognizedErrorFactory() { diff --git a/src/test/java/io/tarantool/driver/integration/TarantoolErrorsIT.java b/src/test/java/io/tarantool/driver/integration/TarantoolErrorsIT.java index 89ebb77e..38a11de8 100644 --- a/src/test/java/io/tarantool/driver/integration/TarantoolErrorsIT.java +++ b/src/test/java/io/tarantool/driver/integration/TarantoolErrorsIT.java @@ -46,8 +46,8 @@ private ProxyTarantoolTupleClient setupClient() { private RetryingTarantoolTupleClient setupRetryingClient(int retries) { ProxyTarantoolTupleClient client = setupClient(); return new RetryingTarantoolTupleClient(client, - TarantoolRequestRetryPolicies - .byNumberOfAttempts(retries).build()); + TarantoolRequestRetryPolicies + .byNumberOfAttempts(retries).build()); } @Test @@ -58,14 +58,13 @@ void testNetworkError_boxErrorUnpackNoConnection() { client.callForSingleResult("box_error_unpack_no_connection", HashMap.class).get(); fail("Exception must be thrown after last retry attempt."); } catch (Throwable e) { + String message = e.getCause().getMessage(); + assertTrue(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "code: 77\n" + - "message: Connection is not established\n" + - "base_type: ClientError\n" + - "type: ClientError\n" + - "trace:") - ); + assertTrue(message.contains("code: 77")); + assertTrue(message.contains("message: Connection is not established")); + assertTrue(message.contains("type: ClientError")); + assertTrue(message.contains("trace:")); } } @@ -80,14 +79,13 @@ void testNetworkError_boxErrorUnpackTimeout() { String.class).get(); fail("Exception must be thrown after last retry attempt."); } catch (Throwable e) { + String message = e.getCause().getMessage(); + assertTrue(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "code: 78\n" + - "message: Timeout exceeded\n" + - "base_type: ClientError\n" + - "type: ClientError\n" + - "trace:") - ); + assertTrue(message.contains("code: 78")); + assertTrue(message.contains("message: Timeout exceeded")); + assertTrue(message.contains("type: ClientError")); + assertTrue(message.contains("trace:")); } } @@ -102,12 +100,11 @@ void testNetworkError_boxErrorTimeout() { String.class).get(); fail("Exception must be thrown after last retry attempt."); } catch (Throwable e) { + String message = e.getCause().getMessage(); + assertTrue(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "InnerErrorMessage:\n" + - "code: 78\n" + - "message: Timeout exceeded") - ); + assertTrue(message.contains("code: 78")); + assertTrue(message.contains("message: Timeout exceeded")); } } @@ -119,13 +116,13 @@ void testNetworkError_crudErrorTimeout() { client.callForSingleResult("crud_error_timeout", HashMap.class).get(); fail("Exception must be thrown after last retry attempt."); } catch (Throwable e) { + String message = e.getCause().getMessage(); + assertTrue(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "Function returned an error: {\"code\":78," + - "\"base_type\":\"ClientError\"," + - "\"type\":\"ClientError\"," + - "\"message\":\"Timeout exceeded\"," - )); + assertTrue(message.contains("\"code\":78")); + assertTrue(message.contains("\"type\":\"ClientError\"")); + assertTrue(message.contains("\"message\":\"Timeout exceeded\"")); + assertTrue(message.contains("\"trace\":")); } } @@ -137,33 +134,32 @@ void testNonNetworkError_boxErrorUnpack() { client.callForSingleResult("box_error_non_network_error", HashMap.class).get(); fail("Exception must be thrown after last retry attempt."); } catch (Throwable e) { + String message = e.getCause().getMessage(); + assertTrue(e.getCause() instanceof TarantoolInternalException); assertFalse(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "code: 40\n" + - "message: Failed to write to disk\n" + - "base_type: ClientError\n" + - "type: ClientError\n" + - "trace:") - ); + assertTrue(message.contains("code: 40")); + assertTrue(message.contains("message: Failed to write to disk")); + assertTrue(message.contains("type: ClientError")); + assertTrue(message.contains("trace:")); } } - @Test - void testNonNetworkError_boxError() { - try { - ProxyTarantoolTupleClient client = setupClient(); - - client.callForSingleResult("raising_error", HashMap.class).get(); - fail("Exception must be thrown after last retry attempt."); - } catch (Throwable e) { - assertTrue(e.getCause() instanceof TarantoolInternalException); - assertFalse(e.getCause() instanceof TarantoolInternalNetworkException); - assertTrue(e.getCause().getMessage().contains( - "InnerErrorMessage:\n" + - "code: 32\n" + - "message:") - ); - } + @Test + void testNonNetworkError_boxError() { + try { + ProxyTarantoolTupleClient client = setupClient(); + + client.callForSingleResult("raising_error", HashMap.class).get(); + fail("Exception must be thrown after last retry attempt."); + } catch (Throwable e) { + String message = e.getCause().getMessage(); + + assertTrue(e.getCause() instanceof TarantoolInternalException); + assertFalse(e.getCause() instanceof TarantoolInternalNetworkException); + assertTrue(message.contains("InnerErrorMessage:")); + assertTrue(message.contains("code: 32")); + assertTrue(message.contains("message:")); } + } } diff --git a/src/test/resources/cartridge/app/roles/api_router.lua b/src/test/resources/cartridge/app/roles/api_router.lua index c83eb1b3..d09232a5 100644 --- a/src/test/resources/cartridge/app/roles/api_router.lua +++ b/src/test/resources/cartridge/app/roles/api_router.lua @@ -1,6 +1,7 @@ local vshard = require('vshard') local cartridge_rpc = require('cartridge.rpc') local fiber = require('fiber') +local crud = require('crud') local log = require('log') local function get_schema() @@ -113,7 +114,10 @@ local function box_error_non_network_error() end local function crud_error_timeout() - return crud.get("test_space", ('x'):rep(2^27)) + return nil, { class_name = 'SelectError', + err = 'Failed to get next object: GetTupleError: Failed to get tuples from storages: UpdateTuplesError: Failed to select tuples from storages: Call: Failed for 07d14fec-f32b-4b90-aa72-e6755273ad56: Function returned an error: {\"code\":78,\"base_type\":\"ClientError\",\"type\":\"ClientError\",\"message\":\"Timeout exceeded\",\"trace\":[{\"file\":\"builtin\\/box\\/net_box.lua\",\"line\":419}]}', + str = 'SelectError: Failed to get next object: GetTupleError: Failed to get tuples from storages: UpdateTuplesError: Failed to select tuples from storages: Call: Failed for 07d14fec-f32b-4b90-aa72-e6755273ad56: Function returned an error: {\"code\":78,\"base_type\":\"ClientError\",\"type\":\"ClientError\",\"message\":\"Timeout exceeded\",\"trace\":[{\"file\":\"builtin\\/box\\/net_box.lua\",\"line\":419}]}' + } end local function init(opts)