无法获取Go http返回错误; '没有接收到数据'

I am doing attempting to build a basic API using Go which returns the results of a SQL query using the PostgreSQL library.

At the moment I can make the program return the values, but I can't get it to return a failed message to the user i.e. some JSON with an error message.

I have an error function as follows :

func handleError(w http.ResponseWriter, err error) {
    if err != nil {
        log.Print(err.Error() + "
") // Logging
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

However the http.Error method doesn't appear to ever return anything. The error thrown is a table that doesn't exist in the database (which gets logged to a text file: i.e. 2016/01/11 23:28:19 pq: relation "building_roof" does not exist

My programmes query code looks like this:

table := pq.QuoteIdentifier(table)
identifier := pq.QuoteIdentifier("ID")
rows, err := db.Query( fmt.Sprintf("SELECT %s, ST_AsText(geom) FROM %s WHERE %s = $1", identifier, table, identifier), feature)
handleError(w, err)

Causing an error just gives a Chrome error:

No data received

ERR_EMPTY_RESPONSE

EDIT Full Code:

package main

import (
    "fmt"
    "encoding/json"
    "os"
    "log"
    "net/http"
    "database/sql"
    "strings"
    "time"
    "github.com/lib/pq"
)


func handler(w http.ResponseWriter, r *http.Request) {

    f, err := os.OpenFile("pgdump_errorlog.txt", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
    log.Print("Couldn't open file")
    defer f.Close()
    log.SetOutput(f)

    // Timing
    start := time.Now()

    // Postgres Credentials
    const (
        DB_USER     = "postgres"
        DB_PASSWORD = "OMITTED" // Removed details !
        DB_PORT     = "OMITTED"
        DB_NAME     = "OMITTED"
    )

    // Postgres Connect
    dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s port=%s sslmode=disable",
                           DB_USER, DB_PASSWORD, DB_NAME, DB_PORT)
    db, err := sql.Open("postgres", dbinfo)
    handleError(w, err)
    defer db.Close()

    table := r.FormValue("table")
    feature := r.FormValue("id")
    if table != "" {

        //Postgres Query
        var (
            id int
            geom string
        )

        table := pq.QuoteIdentifier(table)
        identifier := pq.QuoteIdentifier("ID")
        rows, qerr := db.Query( fmt.Sprintf("SELECT %s, ST_AsText(geom) FROM %s WHERE %s = $1", identifier, table, identifier), feature)
        handleError(w, err)
        defer rows.Close()
        for rows.Next() {
            err := rows.Scan(&id, &geom)
            handleError(w, err)
        }
        err = rows.Err()
        handleError(w, err)

        // Maniplate Strings
        returngeom := strings.Replace(geom, "1.#QNAN", "", -1)
        i := strings.Index(returngeom, "(")
        wkt := strings.TrimSpace(returngeom[:i])
        returngeom = returngeom[i:]

        type WTKJSON struct {
            WTKType   string
            Geometry  string
            Elapsed   time.Duration
        }

        returnjson := WTKJSON{Geometry:  returngeom, WTKType: wkt , Elapsed: time.Since(start)/1000000.0}
        json.NewEncoder(w).Encode(returnjson)

    }

}

func handleError(w http.ResponseWriter, err error) {
    if err != nil {
        log.Print(err.Error() + "
") // Logging
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}


func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

When you are using the http.Error function the error message should a string. For simple testing I would suggest take this line

http.Error(w, err.Error(), http.StatusInternalServerError)

and change it to something like

http.Error(w,"there was an error", http.StatusInternalServerError)

and see if that response comes through. If it does its likely that you are trying to pass something that isn't a string in http.Error()

The following appeared to allow me to return JSON Errors:

func handleError(w http.ResponseWriter, err string) {
    type APIError struct {
        Error string
    }
    re, _ := json.Marshal(APIError{Error: err})
    io.WriteString(w, string(re))
}

Used like so:

rows, err := db.Query( fmt.Sprintf("SELECT %s, ST_AsText(geom) FROM %s WHERE %s = $1", identifier, table, identifier), feature)
        if err != nil {
            handleError(w, err.Error())
            return
        }

Not suggesting this is the best method, but worked in my case.