2015-02-26 6 views
8

के लिए ग्लोबल रिकवरी हैंडलर मैं इसे ईमेल द्वारा भेजने के लिए वैश्विक त्रुटि हैंडलर बनाना चाहता हूं।गोलांग http panic

package main 

import (
    "github.com/gorilla/mux" 
    "log" 
    "net/http" 
) 

func main() { 
    rtr := mux.NewRouter() 
    rtr.HandleFunc("/", withPanic).Methods("GET") 

    http.Handle("/", rtr) 
    log.Println("Listening...") 

    http.ListenAndServe(":3001", http.DefaultServeMux) 
} 

func withPanic(w http.ResponseWriter, r *http.Request) { 
    panic("somewhere here will be panic, but I don't know where exactly") 
} 

इसे वैश्विक कैसे बनाएं। यह आसान होगा अगर मुझे पता चलेगा कि त्रुटि कहाँ होगी

if err != nil { 
sendMeMail(err) 
} 

लेकिन मामलों में क्या करना है जब मुझे नहीं पता कि वास्तव में कोई त्रुटि कब होगी? तो मुझे एक वैश्विक recover आश हैंडलर जोड़ना चाहिए। लेकिन यह कैसे करना है मैं बिल्कुल नहीं जानता।

अद्यतन

मैं main की शुरुआत करने के लिए defer recover जोड़ा लेकिन यह http://localhost:3001 का अनुरोध पर निष्पादित कभी नहीं। तो आतंक ईमेल नहीं है।

package main 

import (
    "errors" 
    "fmt" 
    "github.com/gorilla/mux" 
    "log" 
    "net/http" 
) 

func main() { 
    defer func() { 
     if r := recover(); r != nil { 
      fmt.Println("Recovered in f", r) 
      // find out exactly what the error was and set err 
      var err error 
      switch x := r.(type) { 
      case string: 
       err = errors.New(x) 
      case error: 
       err = x 
      default: 
       err = errors.New("Unknown panic") 
      } 
      if err != nil { 
       // sendMeMail(err) 
       fmt.Println("sendMeMail") 
      } 
     } 
    }() 
    rtr := mux.NewRouter() 
    rtr.HandleFunc("/", withPanic).Methods("GET") 

    http.Handle("/", rtr) 
    log.Println("Listening...") 

    http.ListenAndServe(":3001", http.DefaultServeMux) 
} 

func withPanic(w http.ResponseWriter, r *http.Request) { 
    panic("somewhere here will be panic, but I don't know where exactly") 
} 

उत्तर

20

आप एक वसूली मिडलवेयर

package main 

import (
    "errors" 
    "github.com/gorilla/mux" 
    "log" 
    "net/http" 
) 

func main() { 
    m := mux.NewRouter() 
    m.Handle("/", RecoverWrap(http.HandlerFunc(handler))).Methods("GET") 

    http.Handle("/", m) 
    log.Println("Listening...") 

    http.ListenAndServe(":3001", nil) 

} 

func handler(w http.ResponseWriter, r *http.Request) { 
    panic(errors.New("panicing from error")) 
} 

func RecoverWrap(h http.Handler) http.Handler { 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     var err error 
     defer func() { 
      r := recover() 
      if r != nil { 
       switch t := r.(type) { 
       case string: 
        err = errors.New(t) 
       case error: 
        err = t 
       default: 
        err = errors.New("Unknown error") 
       } 
       sendMeMail(err) 
       http.Error(w, err.Error(), http.StatusInternalServerError) 
      } 
     }() 
     h.ServeHTTP(w, r) 
    }) 
} 

func sendMeMail(err error) { 
    // send mail 
} 

में अपने संचालकों लपेट कर सकते हैं आप अधिक जानकारी के लिए codahale recovery handler या negroni middleware पर एक नज़र डाल सकते हैं।

+1

e.Error() गलती होनी चाहिए। त्रुटि()? –

+0

फिक्स्ड @eyeAppsLLC। – tarrsalah

+0

वास्तव में समाधान की तरह, मेरे लिए काम करता है :) – Danie