2014-05-06 9 views
13

के लिए जाँच मैं जब एक वेब सेवा बुला समय समाप्ति के लिए जाँच करने के लिए निम्नलिखित है, लेकिन मैं विशेष रूप से जाँच करने के लिए अगर वहाँ एक टाइमआउट त्रुटि लौटे चाहते हैं का उपयोग करें।विशेष रूप से टाइमआउट त्रुटि

// Timeout 
type Timeout struct { 
    Connect time.Duration 
    ReadWrite time.Duration 
} 

// TimeoutDialer 
func TimeoutDialer(timeout *Timeout) func(net, addr string) (c net.Conn, err error) { 
    return func(netw, addr string) (net.Conn, error) {  
     conn, err := net.DialTimeout(netw, addr, timeout.Connect) 
     if err != nil { 
      return nil, err 
     } 
     conn.SetDeadline(time.Now().Add(timeout.ReadWrite)) 
     return conn, nil 
    } 
} 

// HttpClient 
func HttpClient(config Config) *http.Client { 
    to := &Timeout{ 
     Connect: time.Duration(config.MaxWait) * time.Second, 
     ReadWrite: time.Duration(config.MaxWait) * time.Second, 
    } 

    return &http.Client{ 
     Transport: &http.Transport{ 
      Dial: TimeoutDialer(to), 
     }, 
    } 
} 
+0

उल्लेख करना भूल गया , यदि आप अपने कनेक्शन पर पूर्ण समय सीमा निर्धारित करने जा रहे हैं तो आपको परिवहन में Keepalive बंद करना चाहिए। अन्यथा आप कनेक्शन का पुन: उपयोग करते समय टाइमआउट प्राप्त करने का जोखिम उठाते हैं। – JimB

उत्तर

35

go1.6 के रूप में, टाइमआउट से सभी त्रुटियों को net.ErrorTimeout() के साथ ठीक से सेट किया जाना चाहिए। आप सभी के लिए जांच करने की आवश्यकता है:

if err, ok := err.(net.Error); ok && err.Timeout() { 

पुराने संस्करणों में, http पैकेज के माध्यम से समय समाप्ति के लिए जाँच और अधिक कठिन था।

  • आप टाइम आउट() के साथ एक *net.OpError प्राप्त कर सकते हैं अगर आप एक समय सीमा अंतर्निहित कनेक्शन पर सेट मारा।
  • आप प्राप्त कर सकते हैं एक tlsHandshakeTimeoutError (है जो स्पष्ट रूप से निर्यात नहीं) है कि net.Error इंटरफ़ेस लागू करता है।
  • आप एक url.Error प्राप्त कर सकते हैं, अगर वहाँ यूआरएल पैकेज में एक समस्या (प्रारंभिक कनेक्शन के दौरान का समय समाप्त)
  • आप "बंद नेटवर्क कनेक्शन का उपयोग" के साथ एक त्रुटि प्राप्त कर सकते हैं अगर आप एक समय समाप्ति के साथ http.Client.Timeout [go1 सेट मारा था .3+] (जो Transport.CancelRequest पर कॉल करता है)। Go1.5 के रूप में, इसमें टाइमआउट संपत्ति सही ढंग से सेट हो जाएगी।

आप एक प्रकार स्विच के साथ एक net.Error के लिए जाँच कर सकते हैं:

साथ
switch err := err.(type) { 
case net.Error: 
    if err.Timeout() { 
     fmt.Println("This was a net.Error with a Timeout") 
    } 
case *url.Error: 
    fmt.Println("This is a *url.Error") 
    if err, ok := err.Err.(net.Error); ok && err.Timeout() { 
     fmt.Println("and it was because of a timeout") 
    } 
} 

जाना < 1.5 आप एक http.Client टाइमआउट के लिए त्रुटि स्ट्रिंग की जाँच करने की आवश्यकता होगी:

if err != nil && strings.Contains(err.Error(), "use of closed network connection") { 
    fmt.Println("Could be from a Transport.CancelRequest") 
} 
+0

यह पूरी तरह से काम करता है, धन्यवाद! –

+0

क्षमा करें, मुझे शायद 'net.Error' पर जोर दे रहा था, क्योंकि आप टाइमआउट वापस प्राप्त कर सकते हैं जो ओपियर नहीं है। – JimB

+1

तो http.Client.Timeout [go1.3 +] के साथ यह जांचना असंभव है कि क्या ट्रांसपोर्ट.कैनलरवेस्ट से त्रुटि टाइमआउट है या नहीं? क्या इसके लिए कोई बग रिपोर्ट है? मेरे लिए संदेश पूरी तरह उलझन में है। –

10

आप net.Error इंटरफेस हैं: एस

मैं इस राशि: मैं इसे कैसे करते हैं। http://golang.org/pkg/net/#Error

if e,ok := err.(net.Error); ok && e.Timeout() { 
    // This was a timeout 
} else if err != nil { 
    // This was an error, but not a timeout 
} 

ध्यान दें कि प्रकार अभिकथन err.(net.Error) सही ढंग से nil मामले को संभालने और ok मूल्य के लिए रिटर्न फाल्स अगर nil, त्रुटि के रूप में दिया जाता है शॉर्ट-सर्किट Timeout जांच करेंगे।

+1

दुर्भाग्य से, कोशिश कर 'प्रतिक्रिया, अरे: = client.Do (अनुरोध) अगर ई, ठीक है:। = अं (net.Error); ठीक && e.Timeout() { \t // यह था एक समय समाप्ति \t fmt.Println ("समय समाप्ति") वापसी } 'मुझे कुछ भी नहीं देता है: एस –

+0

आप यकीन है कि यह एक टाइमआउट त्रुटि है, तो कर रहे हैं? यदि आप गैर-टाइमआउट त्रुटियों को कवर करने के लिए चेक करते हैं तो आप शायद 'और अगर गलती करें' = nil' जोड़ना चाहते हैं। प्राप्त करें: http: //api.vagrant/test – LinearZoetrope

+0

मैं 2 सेकंड के लिए टाइमआउट (maxwait) निर्धारित करते हैं, और 10 सेकंड का एक सोने के साथ कहीं न कहीं है कि एक PHP स्क्रिप्ट के पीछे (इस प्रकार इस समय समाप्त होना चाहिए), त्रुटि है लौट आए। php: पढ़ा टीसीपी 192.168.33.10:80: मैं/हे टाइमआउट –

संबंधित मुद्दे