我正在尝试使用Go构建基本API,它使用PostgreSQL library返回SQL查询的结果。
目前我可以让程序返回值,但我无法让它向用户返回一条失败的消息,即一些带有错误消息的JSON。
我有一个错误函数如下:
func handleError(w http.ResponseWriter, err error) {
if err != nil {
log.Print(err.Error() + "\r\n") // Logging
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
然而,http.Error方法似乎永远不会返回任何内容。抛出的错误是数据库中不存在的表(记录到文本文件中:即2016/01/11 23:28:19 pq:关系“building_roof”不存在
我的程序查询代码如下所示:
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)
导致错误只会导致Chrome错误:
未收到任何数据
ERR_EMPTY_RESPONSE
编辑完整代码:
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() + "\r\n") // Logging
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
答案 0 :(得分:0)
以下似乎允许我返回JSON错误:
func handleError(w http.ResponseWriter, err string) {
type APIError struct {
Error string
}
re, _ := json.Marshal(APIError{Error: err})
io.WriteString(w, string(re))
}
像这样使用:
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
}
不建议这是最好的方法,但在我的情况下有效。
答案 1 :(得分:-1)
当您使用http.Error函数时,错误消息应该是一个字符串。对于简单测试,我建议采取这一行
http.Error(w, err.Error(), http.StatusInternalServerError)
并将其更改为
http.Error(w,"there was an error", http.StatusInternalServerError)
并查看该响应是否通过。如果你有可能尝试传递一些不是http.Error()
中的字符串的东西