You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2022/10/21 10:49:45 UTC

[shardingsphere] branch master updated: Refactor OpenGaussErrorPacketFactory (#21673)

This is an automated email from the ASF dual-hosted git repository.

wuweijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 58bb9506d6f Refactor OpenGaussErrorPacketFactory (#21673)
58bb9506d6f is described below

commit 58bb9506d6f49ec704c70fca88c441b3569d787b
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Fri Oct 21 18:49:36 2022 +0800

    Refactor OpenGaussErrorPacketFactory (#21673)
    
    * Refactor OpenGaussErrorPacketFactory
    
    * Format pom.xml
    
    * Handle null fields of ServerErrorMessage
---
 db-protocol/opengauss/pom.xml                      |  6 ++
 .../generic/OpenGaussErrorResponsePacket.java      | 61 ++++++++++++++++-----
 .../generic/OpenGaussErrorResponsePacketTest.java  | 64 ++++++++--------------
 proxy/bootstrap/pom.xml                            |  5 ++
 proxy/frontend/opengauss/pom.xml                   |  6 ++
 .../opengauss/err/OpenGaussErrorPacketFactory.java | 41 +-------------
 .../err/OpenGaussErrorPacketFactoryTest.java       | 58 +++++++++++++++++++-
 7 files changed, 143 insertions(+), 98 deletions(-)

diff --git a/db-protocol/opengauss/pom.xml b/db-protocol/opengauss/pom.xml
index 31e61083738..88ec367fda0 100644
--- a/db-protocol/opengauss/pom.xml
+++ b/db-protocol/opengauss/pom.xml
@@ -39,5 +39,11 @@
             <artifactId>shardingsphere-postgresql-dialect-exception</artifactId>
             <version>${project.version}</version>
         </dependency>
+        
+        <dependency>
+            <groupId>org.opengauss</groupId>
+            <artifactId>opengauss-jdbc</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/db-protocol/opengauss/src/main/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacket.java b/db-protocol/opengauss/src/main/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacket.java
index 95fb8f10c91..d72e1b929c8 100644
--- a/db-protocol/opengauss/src/main/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacket.java
+++ b/db-protocol/opengauss/src/main/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacket.java
@@ -21,11 +21,11 @@ import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.Postgr
 import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
 import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
+import org.opengauss.util.ServerErrorMessage;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.stream.Collectors;
 
 /**
  * Error response packet for openGauss.
@@ -58,13 +58,11 @@ public final class OpenGaussErrorResponsePacket implements PostgreSQLIdentifierP
     
     public static final char FIELD_TYPE_ERRORCODE = 'c';
     
-    public static final char FIELD_TYPE_SOCKET_ADDRESS = 'a';
-    
     private final Map<Character, String> fields;
     
-    public OpenGaussErrorResponsePacket(final Map<Character, String> serverErrorMessageMap) {
-        fields = new LinkedHashMap<>(serverErrorMessageMap.size(), 1);
-        fields.putAll(serverErrorMessageMap);
+    public OpenGaussErrorResponsePacket(final ServerErrorMessage serverErrorMessage) {
+        fields = new LinkedHashMap<>(13, 1);
+        fillFieldsByServerErrorMessage(serverErrorMessage);
         fillRequiredFieldsIfNecessary();
     }
     
@@ -76,17 +74,50 @@ public final class OpenGaussErrorResponsePacket implements PostgreSQLIdentifierP
         fillRequiredFieldsIfNecessary();
     }
     
-    private void fillRequiredFieldsIfNecessary() {
-        fields.putIfAbsent(FIELD_TYPE_ERRORCODE, "0");
+    private void fillFieldsByServerErrorMessage(final ServerErrorMessage serverErrorMessage) {
+        if (null != serverErrorMessage.getSeverity()) {
+            fields.put(FIELD_TYPE_SEVERITY, serverErrorMessage.getSeverity());
+        }
+        if (null != serverErrorMessage.getSQLState()) {
+            fields.put(FIELD_TYPE_CODE, serverErrorMessage.getSQLState());
+        }
+        if (null != serverErrorMessage.getMessage()) {
+            fields.put(FIELD_TYPE_MESSAGE, serverErrorMessage.getMessage());
+        }
+        if (null != serverErrorMessage.getERRORCODE()) {
+            fields.put(FIELD_TYPE_ERRORCODE, serverErrorMessage.getERRORCODE());
+        }
+        if (null != serverErrorMessage.getDetail()) {
+            fields.put(FIELD_TYPE_DETAIL, serverErrorMessage.getDetail());
+        }
+        if (null != serverErrorMessage.getHint()) {
+            fields.put(FIELD_TYPE_HINT, serverErrorMessage.getHint());
+        }
+        if (serverErrorMessage.getPosition() > 0) {
+            fields.put(FIELD_TYPE_POSITION, serverErrorMessage.getPosition() + "");
+        }
+        if (serverErrorMessage.getInternalPosition() > 0) {
+            fields.put(FIELD_TYPE_INTERNAL_POSITION, serverErrorMessage.getInternalPosition() + "");
+        }
+        if (null != serverErrorMessage.getInternalQuery()) {
+            fields.put(FIELD_TYPE_INTERNAL_QUERY, serverErrorMessage.getInternalQuery());
+        }
+        if (null != serverErrorMessage.getWhere()) {
+            fields.put(FIELD_TYPE_WHERE, serverErrorMessage.getWhere());
+        }
+        if (null != serverErrorMessage.getFile()) {
+            fields.put(FIELD_TYPE_FILE, serverErrorMessage.getFile());
+        }
+        if (serverErrorMessage.getLine() > 0) {
+            fields.put(FIELD_TYPE_LINE, serverErrorMessage.getLine() + "");
+        }
+        if (null != serverErrorMessage.getRoutine()) {
+            fields.put(FIELD_TYPE_ROUTINE, serverErrorMessage.getRoutine());
+        }
     }
     
-    /**
-     * To server error message.
-     *
-     * @return server error message
-     */
-    public String toServerErrorMessage() {
-        return fields.entrySet().stream().map(entry -> entry.getKey() + entry.getValue()).collect(Collectors.joining("\0"));
+    private void fillRequiredFieldsIfNecessary() {
+        fields.putIfAbsent(FIELD_TYPE_ERRORCODE, "0");
     }
     
     @Override
diff --git a/db-protocol/opengauss/src/test/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacketTest.java b/db-protocol/opengauss/src/test/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacketTest.java
index 338e449c11f..430782cdaad 100644
--- a/db-protocol/opengauss/src/test/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacketTest.java
+++ b/db-protocol/opengauss/src/test/java/org/apache/shardingsphere/db/protocol/opengauss/packet/command/generic/OpenGaussErrorResponsePacketTest.java
@@ -17,39 +17,24 @@
 
 package org.apache.shardingsphere.db.protocol.opengauss.packet.command.generic;
 
-import org.apache.shardingsphere.dialect.postgresql.vendor.PostgreSQLVendorError;
-import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLMessageSeverityLevel;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
 import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
+import org.opengauss.util.ServerErrorMessage;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-@RunWith(MockitoJUnitRunner.class)
 public final class OpenGaussErrorResponsePacketTest {
     
-    @Mock
-    private PostgreSQLPacketPayload payload;
-    
     @Test
-    public void assertToServerErrorMessage() {
-        OpenGaussErrorResponsePacket responsePacket = createErrorResponsePacket();
-        String expectedMessage = "SFATAL\0C3D000\0Mdatabase \"test\" does not exist\0c-1\0Ddetail\0Hhint\0P1\0p2\0qinternal query\0"
-                + "Wwhere\0Ffile\0L3\0Rroutine\0a0.0.0.0:1";
-        assertThat(responsePacket.toServerErrorMessage(), is(expectedMessage));
-    }
-    
-    @Test
-    public void assertWrite() {
-        OpenGaussErrorResponsePacket responsePacket = createErrorResponsePacket();
-        responsePacket.write(payload);
+    public void assertWritePacketFromServerErrorMessage() {
+        String encodedMessage = "SFATAL\0C3D000\0Mdatabase \"test\" does not exist\0c-1\0Ddetail\0Hhint\0P1\0p2\0qinternal query\0Wwhere\0Ffile\0L3\0Rroutine\0a0.0.0.0:1";
+        OpenGaussErrorResponsePacket packet = new OpenGaussErrorResponsePacket(new ServerErrorMessage(encodedMessage));
+        PostgreSQLPacketPayload payload = mock(PostgreSQLPacketPayload.class);
+        packet.write(payload);
         verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY);
         verify(payload).writeStringNul("FATAL");
         verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE);
@@ -76,27 +61,22 @@ public final class OpenGaussErrorResponsePacketTest {
         verify(payload).writeStringNul("3");
         verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_ROUTINE);
         verify(payload).writeStringNul("routine");
-        verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_SOCKET_ADDRESS);
-        verify(payload).writeStringNul("routine");
         verify(payload).writeInt1(0);
+        assertThat(packet.getIdentifier(), is(PostgreSQLMessagePacketType.ERROR_RESPONSE));
     }
     
-    private OpenGaussErrorResponsePacket createErrorResponsePacket() {
-        Map<Character, String> serverErrorMessages = new LinkedHashMap<>();
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY, PostgreSQLMessageSeverityLevel.FATAL);
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE, PostgreSQLVendorError.INVALID_CATALOG_NAME.getSqlState().getValue());
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_MESSAGE, "database \"test\" does not exist");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_ERRORCODE, "-1");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_DETAIL, "detail");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_HINT, "hint");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_POSITION, "1");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_INTERNAL_POSITION, "2");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_INTERNAL_QUERY, "internal query");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_WHERE, "where");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_FILE, "file");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_LINE, "3");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_ROUTINE, "routine");
-        serverErrorMessages.put(OpenGaussErrorResponsePacket.FIELD_TYPE_SOCKET_ADDRESS, "0.0.0.0:1");
-        return new OpenGaussErrorResponsePacket(serverErrorMessages);
+    @Test
+    public void assertWritePacketFromSeverityAndMessage() {
+        OpenGaussErrorResponsePacket packet = new OpenGaussErrorResponsePacket("FATAL", "3D000", "database \"test\" does not exist");
+        PostgreSQLPacketPayload payload = mock(PostgreSQLPacketPayload.class);
+        packet.write(payload);
+        verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY);
+        verify(payload).writeStringNul("FATAL");
+        verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE);
+        verify(payload).writeStringNul("3D000");
+        verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_MESSAGE);
+        verify(payload).writeStringNul("database \"test\" does not exist");
+        verify(payload).writeInt1(OpenGaussErrorResponsePacket.FIELD_TYPE_ERRORCODE);
+        verify(payload).writeStringNul("0");
     }
 }
diff --git a/proxy/bootstrap/pom.xml b/proxy/bootstrap/pom.xml
index f75761c3eb2..b0d31657cf4 100644
--- a/proxy/bootstrap/pom.xml
+++ b/proxy/bootstrap/pom.xml
@@ -121,6 +121,11 @@
             <artifactId>mysql-connector-java</artifactId>
             <scope>runtime</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opengauss</groupId>
+            <artifactId>opengauss-jdbc</artifactId>
+            <scope>runtime</scope>
+        </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
diff --git a/proxy/frontend/opengauss/pom.xml b/proxy/frontend/opengauss/pom.xml
index 62134e9b27b..b948da3cc08 100644
--- a/proxy/frontend/opengauss/pom.xml
+++ b/proxy/frontend/opengauss/pom.xml
@@ -38,5 +38,11 @@
             <artifactId>shardingsphere-proxy-frontend-postgresql</artifactId>
             <version>${project.version}</version>
         </dependency>
+        
+        <dependency>
+            <groupId>org.opengauss</groupId>
+            <artifactId>opengauss-jdbc</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactory.java b/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactory.java
index 3c8efab6fa8..e608ea9b759 100644
--- a/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactory.java
+++ b/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactory.java
@@ -20,19 +20,15 @@ package org.apache.shardingsphere.proxy.frontend.opengauss.err;
 import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import lombok.SneakyThrows;
 import org.apache.shardingsphere.db.protocol.opengauss.packet.command.generic.OpenGaussErrorResponsePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLMessageSeverityLevel;
 import org.apache.shardingsphere.dialect.SQLExceptionTransformEngine;
 import org.apache.shardingsphere.dialect.exception.SQLDialectException;
 import org.apache.shardingsphere.dialect.postgresql.vendor.PostgreSQLVendorError;
 import org.apache.shardingsphere.infra.util.exception.external.sql.ShardingSphereSQLException;
+import org.opengauss.util.PSQLException;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.sql.SQLException;
-import java.util.Map;
 
 /**
  * Error packet factory for openGauss.
@@ -40,26 +36,6 @@ import java.util.Map;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class OpenGaussErrorPacketFactory {
     
-    private static final Class<?> PSQL_EXCEPTION_CLASS;
-    
-    private static final Method GET_SERVER_ERROR_MESSAGE_METHOD;
-    
-    private static final Class<?> SERVER_ERROR_MESSAGE_CLASS;
-    
-    private static final Field MESSAGE_PARTS_FIELD;
-    
-    static {
-        try {
-            PSQL_EXCEPTION_CLASS = Class.forName("org.opengauss.util.PSQLException");
-            GET_SERVER_ERROR_MESSAGE_METHOD = PSQL_EXCEPTION_CLASS.getMethod("getServerErrorMessage");
-            SERVER_ERROR_MESSAGE_CLASS = Class.forName("org.opengauss.util.ServerErrorMessage");
-            MESSAGE_PARTS_FIELD = SERVER_ERROR_MESSAGE_CLASS.getDeclaredField("m_mesgParts");
-            MESSAGE_PARTS_FIELD.setAccessible(true);
-        } catch (final ClassNotFoundException | NoSuchMethodException | NoSuchFieldException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-    
     /**
      * Create new instance of openGauss error packet.
      *
@@ -68,7 +44,7 @@ public final class OpenGaussErrorPacketFactory {
      */
     public static OpenGaussErrorResponsePacket newInstance(final Exception cause) {
         if (existsServerErrorMessage(cause)) {
-            return createErrorResponsePacket(getServerErrorMessageMap(cause));
+            return new OpenGaussErrorResponsePacket(((PSQLException) cause).getServerErrorMessage());
         }
         if (cause instanceof SQLException || cause instanceof ShardingSphereSQLException || cause instanceof SQLDialectException) {
             return createErrorResponsePacket(SQLExceptionTransformEngine.toSQLException(cause, "PostgreSQL"));
@@ -77,15 +53,8 @@ public final class OpenGaussErrorPacketFactory {
         return createErrorResponsePacketForUnknownException(cause);
     }
     
-    @SneakyThrows({IllegalAccessException.class, IllegalArgumentException.class, InvocationTargetException.class})
     private static boolean existsServerErrorMessage(final Exception cause) {
-        return PSQL_EXCEPTION_CLASS.isInstance(cause) && null != GET_SERVER_ERROR_MESSAGE_METHOD.invoke(cause);
-    }
-    
-    @SuppressWarnings("unchecked")
-    @SneakyThrows({IllegalAccessException.class, IllegalArgumentException.class, InvocationTargetException.class})
-    private static Map<Character, String> getServerErrorMessageMap(final Exception cause) {
-        return (Map<Character, String>) MESSAGE_PARTS_FIELD.get(GET_SERVER_ERROR_MESSAGE_METHOD.invoke(cause));
+        return cause instanceof PSQLException && null != ((PSQLException) cause).getServerErrorMessage();
     }
     
     private static OpenGaussErrorResponsePacket createErrorResponsePacket(final SQLException cause) {
@@ -95,10 +64,6 @@ public final class OpenGaussErrorPacketFactory {
         return new OpenGaussErrorResponsePacket(PostgreSQLMessageSeverityLevel.ERROR, sqlState, message);
     }
     
-    private static OpenGaussErrorResponsePacket createErrorResponsePacket(final Map<Character, String> serverErrorMessageMap) {
-        return new OpenGaussErrorResponsePacket(serverErrorMessageMap);
-    }
-    
     private static OpenGaussErrorResponsePacket createErrorResponsePacketForUnknownException(final Exception cause) {
         // TODO add FIELD_TYPE_CODE for common error and consider what severity to use
         String message = Strings.isNullOrEmpty(cause.getLocalizedMessage()) ? cause.toString() : cause.getLocalizedMessage();
diff --git a/proxy/frontend/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactoryTest.java b/proxy/frontend/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactoryTest.java
index 2109ba4bf6d..4c5ff2c2f79 100644
--- a/proxy/frontend/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactoryTest.java
+++ b/proxy/frontend/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/err/OpenGaussErrorPacketFactoryTest.java
@@ -17,23 +17,75 @@
 
 package org.apache.shardingsphere.proxy.frontend.opengauss.err;
 
+import lombok.SneakyThrows;
 import org.apache.shardingsphere.db.protocol.opengauss.packet.command.generic.OpenGaussErrorResponsePacket;
-import org.junit.Ignore;
 import org.junit.Test;
+import org.opengauss.util.PSQLException;
+import org.opengauss.util.ServerErrorMessage;
+
+import java.lang.reflect.Field;
+import java.sql.SQLException;
+import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@Ignore("openGauss jdbc driver is not import because of absenting from Maven central repository")
 public final class OpenGaussErrorPacketFactoryTest {
     
+    @Test
+    public void assertNewInstanceWithServerErrorMessage() {
+        String encodedMessage = "SFATAL\0C3D000\0Mdatabase \"test\" does not exist\0c-1\0Ddetail\0Hhint\0P1\0p2\0qinternal query\0Wwhere\0Ffile\0L3\0Rroutine\0a0.0.0.0:1";
+        PSQLException cause = new PSQLException(new ServerErrorMessage(encodedMessage));
+        OpenGaussErrorResponsePacket actual = OpenGaussErrorPacketFactory.newInstance(cause);
+        Map<Character, String> actualFields = getFieldsInPacket(actual);
+        assertThat(actualFields.size(), is(13));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY), is("FATAL"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE), is("3D000"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_MESSAGE), is("database \"test\" does not exist"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_ERRORCODE), is("-1"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_DETAIL), is("detail"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_HINT), is("hint"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_POSITION), is("1"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_INTERNAL_POSITION), is("2"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_INTERNAL_QUERY), is("internal query"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_WHERE), is("where"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_FILE), is("file"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_LINE), is("3"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_ROUTINE), is("routine"));
+    }
+    
+    @Test
+    public void assertNewInstanceWithSQLException() {
+        SQLException cause = new SQLException("database \"test\" does not exist", "3D000", null);
+        OpenGaussErrorResponsePacket actual = OpenGaussErrorPacketFactory.newInstance(cause);
+        Map<Character, String> actualFields = getFieldsInPacket(actual);
+        assertThat(actualFields.size(), is(4));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY), is("ERROR"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE), is("3D000"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_MESSAGE), is("database \"test\" does not exist"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_ERRORCODE), is("0"));
+    }
+    
     @Test
     public void assertNewInstanceWithUnknownException() {
         Exception cause = mock(Exception.class);
         when(cause.getLocalizedMessage()).thenReturn("LocalizedMessage");
         OpenGaussErrorResponsePacket actual = OpenGaussErrorPacketFactory.newInstance(cause);
-        assertThat(actual.toServerErrorMessage(), is("SERROR\0C58000\0MLocalizedMessage\0c0"));
+        Map<Character, String> actualFields = getFieldsInPacket(actual);
+        assertThat(actualFields.size(), is(4));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_SEVERITY), is("ERROR"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_CODE), is("58000"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_MESSAGE), is("LocalizedMessage"));
+        assertThat(actualFields.get(OpenGaussErrorResponsePacket.FIELD_TYPE_ERRORCODE), is("0"));
+    }
+    
+    @SuppressWarnings("unchecked")
+    @SneakyThrows({IllegalAccessException.class, NoSuchFieldException.class})
+    private static Map<Character, String> getFieldsInPacket(final OpenGaussErrorResponsePacket packet) {
+        Field field = OpenGaussErrorResponsePacket.class.getDeclaredField("fields");
+        field.setAccessible(true);
+        return (Map<Character, String>) field.get(packet);
     }
 }