diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHConnectionImpl.java b/src/main/java/ru/yandex/metrika/clickhouse/CHConnectionImpl.java
index 992ab1ae47ed690a0db2981f2f70ef490cadfee7..a4057da13041fd85f89ebdf3a1f12ce6c2af79e6 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/CHConnectionImpl.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/CHConnectionImpl.java
@@ -2,6 +2,7 @@ package ru.yandex.metrika.clickhouse;
 
 import org.apache.http.impl.client.CloseableHttpClient;
 import ru.yandex.metrika.clickhouse.copypaste.CHProperties;
+import ru.yandex.metrika.clickhouse.except.ClickhouseUnhandledException;
 import ru.yandex.metrika.clickhouse.util.CHHttpClientBuilder;
 import ru.yandex.metrika.clickhouse.util.LogProxy;
 import ru.yandex.metrika.clickhouse.util.Logger;
@@ -117,7 +118,7 @@ public class CHConnectionImpl implements CHConnection {
             httpclient.close();
             closed = true;
         } catch (IOException e) {
-            throw new CHException("HTTP client close exception", e);
+            throw new ClickhouseUnhandledException("HTTP client close exception", e, dataSource.getHost(), dataSource.getPort());
         }
     }
 
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHException.java b/src/main/java/ru/yandex/metrika/clickhouse/CHException.java
index de3e900bc1da614c83a1c63ddc492ac6294c7b59..92d6a5630bdceebb194872035b5d707a8814eb7a 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/CHException.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/CHException.java
@@ -7,28 +7,11 @@ import java.sql.SQLException;
  */
 public class CHException extends SQLException {
 
-
-    public CHException(String reason) {
-        super(reason);
-    }
-
-    public CHException(String reason, int vendorCode) {
-        super(reason, null, vendorCode);
-    }
-
-    public CHException(String reason, Throwable cause) {
-        super(reason, cause);
-    }
-
-    public CHException(Throwable cause, String host, int port) {
-        super("ClickHouse exception, host: " + host + ", port: " + port, cause);
-    }
-
     public CHException(int code, Throwable cause, String host, int port) {
-        super("ClickHouse exception, code: " + code + ", host: " + host + ", port: " + port, cause);
+        super("ClickHouse exception, code: " + code + ", host: " + host + ", port: " + port, null, code, cause);
     }
 
-    public CHException(String message, Throwable cause, String host, int port) {
-        super("ClickHouse exception, message: " + message + ", host: " + host + ", port: " + port, cause);
+    public CHException(int code, String message, Throwable cause, String host, int port) {
+        super("ClickHouse exception, message: " + message + ", host: " + host + ", port: " + port, null, code, cause);
     }
 }
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHStatementImpl.java b/src/main/java/ru/yandex/metrika/clickhouse/CHStatementImpl.java
index 94d8cbf4718ddafb44849f9481248a4a3e32414a..afddcb257904cb099c8470b8e094d10110cba8f0 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/CHStatementImpl.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/CHStatementImpl.java
@@ -74,8 +74,9 @@ public class CHStatementImpl implements CHStatement {
             );
             currentResult.setMaxRows(maxRows);
             return currentResult;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (Exception e){
+            CopypasteUtils.close(is);
+            throw ClickhouseExceptionSpecifier.specify(e, source.getHost(), source.getPort());
         }
     }
 
@@ -105,7 +106,7 @@ public class CHStatementImpl implements CHStatement {
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
-            if (is != null) try {is.close();} catch (IOException ignored) { }
+            CopypasteUtils.close(is);
         }
     }
 
@@ -117,7 +118,7 @@ public class CHStatementImpl implements CHStatement {
             //noinspection StatementWithEmptyBody
             while (rs.next()) {}
         } finally {
-            try { if (rs != null) rs.close(); } catch (Exception ignored) {}
+            CopypasteUtils.close(rs);
         }
         return 1;
     }
@@ -419,7 +420,7 @@ public class CHStatementImpl implements CHStatement {
                     }
                     chMessage = CopypasteUtils.toString(messageStream);
                 } catch (IOException e) {
-                    chMessage = "error while read response "+ e.getMessage();
+                    chMessage = "error while read response " + e.getMessage();
                 }
                 EntityUtils.consumeQuietly(entity);
                 throw ClickhouseExceptionSpecifier.specify(chMessage, source.getHost(), source.getPort());
@@ -432,12 +433,14 @@ public class CHStatementImpl implements CHStatement {
                 is = baos.convertToInputStream();
             }
             return is;
-        } catch (IOException e) {
+        } catch (CHException e){
+            throw e;
+        } catch (Exception e) {
             log.info("Error during connection to " + source + ", reporting failure to data source, message: " + e.getMessage());
             EntityUtils.consumeQuietly(entity);
-            try { if (is != null) is.close(); } catch (IOException ignored) { }
+            CopypasteUtils.close(is);
             log.info("Error sql: " + sql);
-            throw new CHException("Unknown IO exception", e);
+            throw ClickhouseExceptionSpecifier.specify(e, source.getHost(), source.getPort());
         }
     }
 
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseApiException.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseApiException.java
index 67e36dfb173e65b3d012814f85598e5871d80ad4..3d91d75aabc6e2fd930d305e441a9cc602f41025 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseApiException.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseApiException.java
@@ -7,8 +7,6 @@ import ru.yandex.metrika.clickhouse.CHException;
  * @since 16.02.15
  */
 public class ClickhouseApiException extends CHException {
-    public static final String MESSAGE =
-            "Запрос не может быть обработан из-за внутренней ошибки. Мы проанализируем и постараемся устранить причину как можно быстрее. Пожалуйста, не отправляйте запрос повторно.";
 
     public ClickhouseApiException(Integer code, Throwable cause, String host, int port) {
         super(code, cause, host, port);
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseDbException.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseDbException.java
index 03fa2a2b46450c95c409ee0ac22fa8a18a2cef46..d8655c7aff975ca0b926e22beea908bd43f5055f 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseDbException.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseDbException.java
@@ -7,8 +7,6 @@ import ru.yandex.metrika.clickhouse.CHException;
  * @since 16.02.15
  */
 public class ClickhouseDbException extends CHException {
-    public static final String MESSAGE =
-            "Запрос не может быть обработан в данный момент из-за возросшей нагрузки. Пожалуйста, отправьте запрос повторно через несколько минут.";
 
     public ClickhouseDbException(Integer code, Throwable cause, String host, int port) {
         super(code, cause, host, port);
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseErrorCode.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseErrorCode.java
index 5c2a7557e797005b920cf54f7e48fbc08d86bef8..8ed2963a2487b3f8f5a014582b6b872ca230feae 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseErrorCode.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseErrorCode.java
@@ -29,7 +29,8 @@ public enum ClickhouseErrorCode {
     NETWORK_ERROR                           (210),
     EMPTY_QUERY                             (211),
     MEMORY_LIMIT_EXCEEDED                   (241),
-    POCO_EXCEPTION                          (1000);
+    POCO_EXCEPTION                          (1000),
+    UNKNOWN_EXCEPTION                       (1002);
 
     public final Integer code;
 
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseExceptionSpecifier.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseExceptionSpecifier.java
index 43b51ff57d230615406bda832e562936492f1176..56c3b489b6e90f29ed0200c8d15e6334b7a6e445 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseExceptionSpecifier.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseExceptionSpecifier.java
@@ -5,11 +5,13 @@ import ru.yandex.metrika.clickhouse.CHException;
 import ru.yandex.metrika.clickhouse.util.CopypasteUtils;
 import ru.yandex.metrika.clickhouse.util.Logger;
 
+import java.net.ConnectException;
 import java.net.SocketTimeoutException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+
 /**
  * @author lemmsh
  * @since 7/17/14
@@ -86,22 +88,33 @@ public final class ClickhouseExceptionSpecifier {
      * Очень надеемся, что кто-то будет в эти тесты смотреть и актуализировать парсинг.
      */
     public static CHException specify(String clickhouseMessage, Throwable cause, String host, int port) {
-        if (CopypasteUtils.isBlank(clickhouseMessage) && cause != null) {
+        if (CopypasteUtils.isEmpty(clickhouseMessage) && cause != null) {
             if (cause instanceof SocketTimeoutException)
-                return new ClickhouseQueryException(ClickhouseErrorCode.SOCKET_TIMEOUT.code, cause, host, port);
-            else if (cause instanceof ConnectTimeoutException)
-                return new ClickhouseQueryException(ClickhouseErrorCode.NETWORK_ERROR.code, cause, host, port);
+                // если приехал STE, то скажем, что это запрос плохой, это не то же самое, что SOCKET_TIMEOUT от кликхауса
+                // хотя это также может значить падающий кликхаус, посмотрим что выглядит правдоподобнее
+                return new ClickhouseQueryException(ClickhouseErrorCode.TIMEOUT_EXCEEDED.code, cause, host, port);
+            else if (cause instanceof ConnectTimeoutException || cause instanceof ConnectException)
+                // не смогли соединиться с кликхаусом за connectTimeout - в принципе, может быть никто не виноват
+                // среди наших сущностей (query/api/db), но обвинить кого-то надо, и это будет db
+                return new ClickhouseDbException(ClickhouseErrorCode.NETWORK_ERROR.code, cause, host, port);
             else
                 return new ClickhouseUnhandledException(cause, host, port);
         }
         try {
-            // быстро и опасно
-            int code = Integer.parseInt(clickhouseMessage.substring(clickhouseMessage.indexOf(' ') + 1, clickhouseMessage.indexOf(',')));
+            int code;
+            if(clickhouseMessage.startsWith("Poco::Exception. Code: 1000, ")) {
+                code = 1000;
+            } else {
+                // быстро и опасно  Code: 175, e.displayText() = DB::Exception:
+                code = Integer.parseInt(clickhouseMessage.substring(clickhouseMessage.indexOf(' ') + 1, clickhouseMessage.indexOf(',')));
+            }
             // ошибку в изначальном виде все-таки укажем
             Throwable messageHolder = cause != null ? cause : new Throwable(clickhouseMessage);
-            ClickhouseExceptionFactory clickhouseExceptionFactory = FACTORIES.get(code);
-            if (clickhouseExceptionFactory == null) clickhouseExceptionFactory = DEFAULT_FACTORY;
-            return clickhouseExceptionFactory.create(code, messageHolder, host, port);
+            if (FACTORIES.containsKey(code)) {
+                return FACTORIES.get(code).create(code, messageHolder, host, port);
+            } else {
+                return DEFAULT_FACTORY.create(code, messageHolder, host, port);
+            }
         } catch (Exception e) {
             log.error("Unsupported clickhouse error format, please fix ClickhouseExceptionSpecifier, message: "
                             + clickhouseMessage + ", error: " + e.getMessage());
@@ -113,4 +126,4 @@ public final class ClickhouseExceptionSpecifier {
         CHException create(Integer code, Throwable cause, String host, int port);
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseQueryException.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseQueryException.java
index c2625935359cfd45b69746de93b1aa878042641a..3427f1c85e7c4682943e1a165f568eac039c849b 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseQueryException.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseQueryException.java
@@ -8,8 +8,6 @@ import ru.yandex.metrika.clickhouse.CHException;
  * @since 16.02.15
  */
 public class ClickhouseQueryException extends CHException {
-    public static final String MESSAGE =
-            "Запрос слишком сложный и не может быть обработан. Пожалуйста, уменьшите интервал дат запроса либо включите/уменьшите семплирование и повторите запрос.";
 
     public ClickhouseQueryException(Integer code, Throwable cause, String host, int port) {
         super(code, cause, host, port);
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseUnhandledException.java b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseUnhandledException.java
index e47d500970e180bf1cc1f01dad04f4e0c279ea76..016a6805efbec8224b2d094959e295f63f2544f8 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseUnhandledException.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/except/ClickhouseUnhandledException.java
@@ -7,16 +7,14 @@ import ru.yandex.metrika.clickhouse.CHException;
  * @since 16.02.15
  */
 public class ClickhouseUnhandledException extends CHException {
-    public static final String MESSAGE =
-            "Запрос не может быть обработан по неизвестной причине. Мы проанализируем и постараемся устранить причину как можно быстрее. Пожалуйста, отправьте запрос повторно через несколько минут.";
 
     public ClickhouseUnhandledException(Throwable cause, String host, int port) {
-        super(cause, host, port);
+        super(ClickhouseErrorCode.UNKNOWN_EXCEPTION.code, cause, host, port);
     }
 
 
     public ClickhouseUnhandledException(String message, Throwable cause, String host, int port) {
-        super(message, cause, host, port);
+        super(ClickhouseErrorCode.UNKNOWN_EXCEPTION.code, message, cause, host, port);
     }
 
     public ClickhouseUnhandledException(Integer code, Throwable cause, String host, int port) {
diff --git a/src/main/java/ru/yandex/metrika/clickhouse/util/CopypasteUtils.java b/src/main/java/ru/yandex/metrika/clickhouse/util/CopypasteUtils.java
index 681c6e19503aeacd93dc20c90adc428865606275..0059b0c1431f2168ff14573552fb4a242536040b 100644
--- a/src/main/java/ru/yandex/metrika/clickhouse/util/CopypasteUtils.java
+++ b/src/main/java/ru/yandex/metrika/clickhouse/util/CopypasteUtils.java
@@ -1,10 +1,9 @@
 package ru.yandex.metrika.clickhouse.util;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 import java.nio.charset.Charset;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -14,6 +13,7 @@ import java.util.List;
  */
 public class CopypasteUtils {
 
+    private static final Logger log = Logger.of(CopypasteUtils.class);
     public static final Charset UTF_8 = Charset.forName("UTF-8");
 
     /////// Metrika code //////
@@ -191,4 +191,22 @@ public class CopypasteUtils {
         return total;
     }
 
+    public static void close(Closeable closeable){
+        if (closeable == null) return;
+        try{
+            closeable.close();
+        } catch (IOException e){
+            log.error("can not close stream: " + e.getMessage());
+        }
+    }
+
+    public static void close(ResultSet rs){
+        if (rs == null) return;
+        try{
+            rs.close();
+        } catch (SQLException e){
+            log.error("can not close resultset: " + e.getMessage());
+        }
+    }
+
 }