diff --git a/conn.go b/conn.go index 62bd12d..3c3738b 100644 --- a/conn.go +++ b/conn.go @@ -247,10 +247,15 @@ func (c *conn) exec(ctx context.Context, query string, args []driver.Value) (dri return nil, err } body, err := c.doRequest(ctx, req) - if body != nil { - body.Close() + if err != nil { + if body != nil { + body.Close() + } + + return emptyResult, err } - return emptyResult, err + + return emptyResult, noticeError(body) } func (c *conn) doRequest(ctx context.Context, req *http.Request) (io.ReadCloser, error) { diff --git a/helpers.go b/helpers.go index 3b4cf25..5c43947 100644 --- a/helpers.go +++ b/helpers.go @@ -2,6 +2,7 @@ package clickhouse import ( "bytes" + "io" "net/http" "strings" "time" @@ -11,6 +12,8 @@ var ( escaper = strings.NewReplacer(`\`, `\\`, `'`, `\'`) dateFormat = "2006-01-02" timeFormat = "2006-01-02 15:04:05" + + exceptionMarker = "DB::Exception" ) func escape(s string) string { @@ -40,6 +43,22 @@ func readResponse(response *http.Response) (result []byte, err error) { return } +func noticeError(body io.ReadCloser) (err error) { + if body == nil { + return nil + } + + buf := new(bytes.Buffer) + defer body.Close() + _, err = buf.ReadFrom(body) + msg := buf.String() + if strings.Contains(msg, exceptionMarker) { + return newError(msg) + } + + return nil +} + func numOfColumns(data []byte) int { var cnt int for _, ch := range data {