5

我有一个连接到服务器以向其发送一些命令的 python 程序,但有时我会收到此错误

TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

在以前这样的情况下,我会使用这样的东西

try:
            do something
        except KeyError:
            do something else

我可以在同样的情况下做同样的事情吗?

try:
                do something
            except TimeoutError:
               do something again

如果是这样,我会在除了 TimeoutError 之后做什么?我会再次执行相同的命令吗?

4

4 回答 4

23

我可以在同样的情况下做同样的事情吗

是的!您可以将try/except用于任何异常,并TimeoutError没有什么特别之处。

如果是这样,我会在除了 TimeoutError 之后做什么?我会再次执行相同的命令吗?

如果您只想重试一次,并让第二次超时算作真正的错误,是的:

try:
    do something
except TimeoutError:
    do something

(如果“做某事”不仅仅是一个简单的陈述,您可能希望将代码分解出来,这样您就不会重复自己。)

但是,如果您想多次重试,您可能需要一个循环:

for _ in range(max_retries):
    try:
        do something
        break
    except TimeoutError:
        pass

您可能希望在 中添加一个else子句以for区分这两种情况(成功,并且执行了break, vs. 从未成功,只是尝试用完了)。


由于这里的想法通常是处理可能暂时的错误,因此您可能需要添加其他内容,例如:

  • 重新提出错误,或提出不同的错误,之后max_retries
  • 以逐渐更高的级别记录日志(例如,单个故障的调试消息,但 `max_retries 的警告)。
  • 使用指数退避重试(等待 1 秒,然后等待 2、4、8,...)。
  • 将 URL 推送到工作队列的末尾,而不是立即重试。(URL, retry_count)如果您还需要max_retries逻辑,则可以使用对,(URL, timestamp)如果您还需要指数退避,则可以使用对,或者如果您想要两者都使用两者。(当然,这仅在您不关心响应顺序或可以在最后重新排序时才有效。)
  • 针对不同异常的不同规则(例如,500、502、503 和 504 错误都可能由服务器或代理上的过载引起,但最佳重试逻辑可能不同——2018 年的最佳启发式方法可能与 2010 年或2025)。

对于复杂的组合,重试装饰器,如jterrace 的有用答案中链接的装饰器,是包装行为的好方法。

于 2013-09-17T01:49:59.800 回答
6

您可以像您提到的那样捕获 TimeoutError :

import socket
import sys
try:
  dosomething()
except socket.TimeoutError:
  print >> sys.stderr, 'Retrying after TimeoutError'
  dosomething()

您还可以在函数上使用重试装饰器模式

@retry(socket.TimeoutError)
def dosomething():
    # code that causes a TimeoutError
    ...
于 2013-09-17T01:48:28.040 回答
2
def f():
    pass #insert code here

错误后重复一次:

try:
    f()
except TimeoutError:
    f()

或者循环直到成功:

while True:
    try:
        f()
        break
    except TimeoutError:
        pass

或数量有限:

attempts = 3
while attempts:
    try:
        f()
        break
    except TimeoutError:
        attempts -= 1
于 2013-09-17T01:48:55.883 回答
-1

请运行每个示例,它们已准备就绪!

示例 1

import sys

try:
    incorrect.syntaxThatIJustMadeUP()
except:
    print((sys.exc_info()[0])) #Now you know what to except and CATCH
else:
    print("You will never see this message")

示例 2

import sys

try:
    incorrect.syntaxThatIJustMadeUP()
except NameError:
    print("There is a problem with your SYNTAX Dude!")
except:
    print((sys.exc_info()[0])) #Incase another uncontrollable network problem occurs, User rages-Snaps IJ45
else:
    print("You will never see this message unless TRY suceeds")
    print("Why not put this try in a loop")
于 2014-11-23T02:44:42.753 回答