fix: 在 handler 中检查错误,不再静默丢弃
This commit is contained in:
+14
-4
@@ -58,7 +58,10 @@ func (h *GenerateHandler) Generate(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendEvent := func(event string, data interface{}) {
|
sendEvent := func(event string, data interface{}) {
|
||||||
jsonData, _ := json.Marshal(data)
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
jsonData = []byte(`{"error":"failed to marshal event data"}`)
|
||||||
|
}
|
||||||
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
@@ -74,7 +77,14 @@ func (h *GenerateHandler) Generate(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save analysis to DB
|
// Save analysis to DB
|
||||||
resultJSON, _ := json.Marshal(pr)
|
resultJSON, err := json.Marshal(pr)
|
||||||
h.db.Exec(`INSERT INTO analyses (repo_id, type, base_ref, head_ref, result) VALUES (?, 'pr_description', ?, ?, ?)`,
|
if err != nil {
|
||||||
id, req.Base, req.Head, string(resultJSON))
|
sendEvent("error", map[string]interface{}{"message": "marshal result: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := h.db.Exec(`INSERT INTO analyses (repo_id, type, base_ref, head_ref, result) VALUES (?, 'pr_description', ?, ?, ?)`,
|
||||||
|
id, req.Base, req.Head, string(resultJSON)); err != nil {
|
||||||
|
sendEvent("error", map[string]interface{}{"message": "save analysis: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-9
@@ -43,6 +43,10 @@ func (h *ReposHandler) ListRepos(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
if repos == nil {
|
if repos == nil {
|
||||||
repos = []gin.H{}
|
repos = []gin.H{}
|
||||||
}
|
}
|
||||||
@@ -61,9 +65,18 @@ func (h *ReposHandler) DeleteRepo(c *gin.Context) {
|
|||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
os.RemoveAll(localPath)
|
if err := os.RemoveAll(localPath); err != nil {
|
||||||
h.db.Exec(`DELETE FROM analyses WHERE repo_id = ?`, id)
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "remove repo dir: " + err.Error()})
|
||||||
h.db.Exec(`DELETE FROM repositories WHERE id = ?`, id)
|
return
|
||||||
|
}
|
||||||
|
if _, err := h.db.Exec(`DELETE FROM analyses WHERE repo_id = ?`, id); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "delete analyses: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := h.db.Exec(`DELETE FROM repositories WHERE id = ?`, id); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "delete repository: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,17 +93,33 @@ func (h *ReposHandler) CleanupRepos(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var cleaned []int64
|
var cleaned []int64
|
||||||
|
var errs []string
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id int64
|
var id int64
|
||||||
var localPath string
|
var localPath string
|
||||||
if rows.Scan(&id, &localPath) == nil {
|
if rows.Scan(&id, &localPath) == nil {
|
||||||
os.RemoveAll(localPath)
|
if err := os.RemoveAll(localPath); err != nil {
|
||||||
h.db.Exec(`DELETE FROM analyses WHERE repo_id = ?`, id)
|
errs = append(errs, fmt.Sprintf("remove %d: %s", id, err.Error()))
|
||||||
h.db.Exec(`DELETE FROM repositories WHERE id = ?`, id)
|
continue
|
||||||
|
}
|
||||||
|
if _, err := h.db.Exec(`DELETE FROM analyses WHERE repo_id = ?`, id); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("delete analyses %d: %s", id, err.Error()))
|
||||||
|
}
|
||||||
|
if _, err := h.db.Exec(`DELETE FROM repositories WHERE id = ?`, id); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("delete repo %d: %s", id, err.Error()))
|
||||||
|
}
|
||||||
cleaned = append(cleaned, id)
|
cleaned = append(cleaned, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"cleaned": cleaned})
|
if err := rows.Err(); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result := gin.H{"cleaned": cleaned}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
result["errors"] = errs
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloneRepo handles POST /api/repos with SSE progress events.
|
// CloneRepo handles POST /api/repos with SSE progress events.
|
||||||
@@ -119,7 +148,10 @@ func (h *ReposHandler) CloneRepo(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendEvent := func(event string, data interface{}) {
|
sendEvent := func(event string, data interface{}) {
|
||||||
jsonData, _ := json.Marshal(data)
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
jsonData = []byte(`{"error":"failed to marshal event data"}`)
|
||||||
|
}
|
||||||
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
@@ -155,7 +187,11 @@ func (h *ReposHandler) CloneRepo(c *gin.Context) {
|
|||||||
sendEvent("error", map[string]interface{}{"message": "save to db: " + err.Error()})
|
sendEvent("error", map[string]interface{}{"message": "save to db: " + err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
repoID, _ := res.LastInsertId()
|
repoID, err := res.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
sendEvent("error", map[string]interface{}{"message": "get repo id: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
sendEvent("complete", map[string]interface{}{
|
sendEvent("complete", map[string]interface{}{
|
||||||
"repo_id": repoID,
|
"repo_id": repoID,
|
||||||
|
|||||||
+27
-6
@@ -90,7 +90,10 @@ func (h *ReviewHandler) Review(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendEvent := func(event string, data interface{}) {
|
sendEvent := func(event string, data interface{}) {
|
||||||
jsonData, _ := json.Marshal(data)
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
jsonData = []byte(`{"error":"failed to marshal event data"}`)
|
||||||
|
}
|
||||||
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", event, jsonData)
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
@@ -106,15 +109,25 @@ func (h *ReviewHandler) Review(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save analysis to DB with full review result
|
// Save analysis to DB with full review result
|
||||||
resultJSON, _ := json.Marshal(reviewResult)
|
resultJSON, err := json.Marshal(reviewResult)
|
||||||
|
if err != nil {
|
||||||
|
sendEvent("error", map[string]interface{}{"message": "marshal result: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
res, err := h.db.Exec(`INSERT INTO analyses (repo_id, type, base_ref, head_ref, result) VALUES (?, 'code_review', ?, ?, ?)`,
|
res, err := h.db.Exec(`INSERT INTO analyses (repo_id, type, base_ref, head_ref, result) VALUES (?, 'code_review', ?, ?, ?)`,
|
||||||
id, req.Base, req.Head, string(resultJSON))
|
id, req.Base, req.Head, string(resultJSON))
|
||||||
if err == nil {
|
if err != nil {
|
||||||
analysisID, _ := res.LastInsertId()
|
sendEvent("error", map[string]interface{}{"message": "save analysis: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
analysisID, err := res.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
sendEvent("error", map[string]interface{}{"message": "get analysis id: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
sendEvent("analysis_saved", map[string]interface{}{
|
sendEvent("analysis_saved", map[string]interface{}{
|
||||||
"analysis_id": analysisID,
|
"analysis_id": analysisID,
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveNotes handles POST /api/repos/:id/review/notes — upsert a review note.
|
// SaveNotes handles POST /api/repos/:id/review/notes — upsert a review note.
|
||||||
@@ -202,6 +215,10 @@ func (h *ReviewHandler) ListReviews(c *gin.Context) {
|
|||||||
"created_at": createdAt,
|
"created_at": createdAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if analyses == nil {
|
if analyses == nil {
|
||||||
analyses = []map[string]interface{}{}
|
analyses = []map[string]interface{}{}
|
||||||
@@ -305,7 +322,11 @@ func (h *ReviewHandler) GeneratePDF(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return PDF as download
|
// Return PDF as download
|
||||||
filename := fmt.Sprintf("pr-helper-review-%s.pdf", createdAt[:10])
|
dateStr := createdAt
|
||||||
|
if len(dateStr) > 10 {
|
||||||
|
dateStr = dateStr[:10]
|
||||||
|
}
|
||||||
|
filename := fmt.Sprintf("pr-helper-review-%s.pdf", dateStr)
|
||||||
c.Header("Content-Type", "application/pdf")
|
c.Header("Content-Type", "application/pdf")
|
||||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
||||||
c.Data(http.StatusOK, "application/pdf", pdfBytes)
|
c.Data(http.StatusOK, "application/pdf", pdfBytes)
|
||||||
|
|||||||
Reference in New Issue
Block a user