我正試圖撰寫一些自定義的例外處理,但一直遇到 "TypeError: 捕捉不繼承自BaseException的類是不允許的 "錯誤。 我有一個名為 NodeError 的基礎例外類,它繼承自 Exception。 從那里,我有幾個繼承自NodeError的自定義例外。
web3模塊使用請求模塊與節點進行通信。 我的測驗不斷嘗試從節點上獲取tx計數,當它這樣做的時候,我試圖通過禁用我的網卡來模擬一個故障。 我試圖在get_tx_count()中捕捉requests.exceptions.ConnectionError,并引發我自己的例外。 根據堆疊跟蹤,它似乎正確地擊中了 NodeConnectionError 自定義例外,但隨后得到了另一個例外,并抱怨說捕獲了不繼承于 BaseException 的類。
不確定它為什么認為我沒有繼承自 BaseException,但我感覺它與首先捕獲請求例外有關。
堆疊跟蹤:
Traceback (most recent call last):
檔案 "C:Python39libsite-packagesurllib3connection.py", line 169, in _new_conn
conn = connection.create_connection(
檔案 "C:Python39libsite-packagesurllib3utilconnection.py", line 73, in create_connection
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM)。
檔案 "C:Python39libsocket.py", line 953, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags) 。
socket.gaierror。[Errno 11001] getaddrinfo failed
在處理上述例外的程序中,發生了另一個例外。
回溯(最近一次呼叫)。
檔案 "C:Python39libsite-packagesurllib3connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
檔案 "C:Python39libsite-packagesurllib3connectionpool.py", line 382, in _make_request
self._validate_conn(conn)
檔案 "C:Python39libsite-packagesurllib3connectionpool.py", line 1010, in _validate_conn
conn.connect()
檔案 "C:Python39libsite-packagesurllib3connection.py", line 353, in connect
conn = self._new_conn()
檔案 "C:Python39libsite-packagesurllib3connection.py", line 181, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x000001413971AB50> 。建立一個新的連接失敗。[Errno 11001] getaddrinfo failed
在處理上述例外的程序中,發生了另一個例外。
回溯(最近一次呼叫)。
檔案 "C:Python39libsite-packages
equestsadapters.py",第439,in send
resp = conn.urlopen(
檔案 "C:Python39libsite-packagesurllib3connectionpool.py", line 755, in urlopen
retries = retries.increment(
檔案"C:Python39libsite-packagesurllib3util
etry.py",第574行,in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError。HTTPSConnectionPool(host='matic-mainnet-full-rpc.bwarelabs.com', port=443)。超過最大重試次數with url: / (Causeused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001413971AB50>: 建立一個新的連接失敗。[Errno 11001] getaddrinfo failed'))
在處理上述例外的程序中,發生了另一個例外。
回溯(最近一次呼叫)。
檔案 "C: extest.py", line 87, in get_tx_count
nonce = w3.eth.get_transaction_count(address)
檔案 "C:Python39libsite-packagesweb3module.py", line 57, in caller
result = w3.manager.request_blocking(method_str,
檔案 "C:Python39libsite-packagesweb3manager.py", line 186, in request_blocking
response = self._make_request(method, params)
檔案 "C:Python39libsite-packagesweb3manager.py", line 147, in _make_request
return request_func(method, params)
檔案 "cytoolz/functoolz.pyx", 行 250, in cytoolz.functoolz.curry.__call__
return self.func(*args, **kwargs)
檔案 "C:Python39libsite-packagesweb3middlewareformatting.py", line 76, in apply_formatters
response = make_request(method, params)
檔案 "C:Python39libsite-packagesweb3middlewaregas_price_strategy.py", 行 84, in middleware
return make_request(method, params)
檔案 "cytoolz/functoolz.pyx", line 250, in cytoolz.functoolz.curry.__call__
return self.func(*args, **kwargs)
檔案 "C:Python39libsite-packagesweb3middlewareformatting.py", line 74, in apply_formatters
response = make_request(method, formatted_params)
檔案 "C:Python39libsite-packagesweb3middlewareattrdict.py", 行 33, in middleware
回應 = make_request(method, params)
檔案 "cytoolz/functoolz.pyx", 行 250, in cytoolz.functoolz.curry.__call__
return self.func(*args, **kwargs)
檔案 "C:Python39libsite-packagesweb3middlewareformatting.py", line 74, in apply_formatters
response = make_request(method, formatted_params)
檔案 "cytoolz/functoolz.pyx", 行 250, in cytoolz.functoolz.curry.__call__
return self.func(*args, **kwargs)
檔案 "C:Python39libsite-packagesweb3middlewareformatting.py", line 76, in apply_formatters
response = make_request(method, params)
檔案 "cytoolz/functoolz.pyx", 行 250, in cytoolz.functoolz.curry.__call__
return self.func(*args, **kwargs)
檔案 "C:Python39libsite-packagesweb3middlewareformatting.py", line 74, in apply_formatters
response = make_request(method, formatted_params)
檔案 "C:Python39libsite-packagesweb3middlewareuffered_gas_estimate.py", 行 40, in middleware
return make_request(method, params)
檔案 "C:Python39libsite-packagesweb3middlewareexception_retry_request.py", 行 105, in middleware
return make_request(method, params)
檔案 "C:Python39libsite-packagesweb3providers
pc.py",第88,in make_request
raw_response = make_post_request(
檔案"C:Python39libsite-packagesweb3\_utils
equest.py",行48,in make_post_request
response = session.post(endpoint_uri, data=data, *args, **kwargs) # type: ignore >。
檔案 "C:Python39libsite-packages
equestssessions.py", 行 590, in post
return self.request('POST'/span>, url, data=data, json=json, **kwargs)
檔案 "C:Python39libsite-packages
equestssessions.py",第542行,in request
resp = self.send(prep, **send_kwargs)
檔案 "C:Python39libsite-packages
equestssessions.py",第655行,in send
r = adapter.send(request, **kwargs)
檔案 "C:Python39libsite-packages
equestsadapters.py", 行 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError。HTTPSConnectionPool(host='matic-mainnet-full-rpc.bwarelabs.com', port=443) 。超過最大重試次數with url: / (Causeused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001413971AB50>: 建立一個新的連接失敗。[Errno 11001] getaddrinfo failed'))
上述例外是導致以下例外的直接原因。
回溯(最近一次呼叫)。
檔案 "C: extest.py", line 114, in main
print(get_tx_count(w3, address) )
檔案 "C: extest.py", line 90, in get_tx_count
raise NodeConnectionError(w3) from e
__main__.NodeConnectionError: 一個錯誤發生了 與節點在 https://matic-mainnet-full-rpc.bwarelabs.com:443.的對話中發生了web3連接錯誤。
在處理上述例外的程序中,發生了另一個例外。
回溯(最近一次呼叫)。
檔案 "C: extest.py", line 140, in <module>
main()
檔案 "C: extest.py", line 116, in main
except NodeNotConnected(w3.provider.endpoint_uri, w3) 。
TypeError: 捕捉不繼承自BaseException的類 是 不允許的
測驗代碼:
from web3 import Web3
from time import sleep
from requests.exceptions import ConnectionError, ConnectTimeout, HTTPError
import sys
class NodeError(Exception)。
""節點錯誤的基本例外""。
def __init__(self, url, msg=None)。
if msg is None:
msg = f "在{url}的節點發生錯誤。"。
super().__init__(msg)
自我.url = url
class NodeNotConnected(NodeError)。
""web3無法連接到一個節點""。
def __init__(self, url, w3=None):
msg = f "一個web3連接無法建立在URL {url}。"。
super().__init__(url, msg=msg)
self.w3 = w3
class NodeConnectionError(NodeError)。
""A web3 error occurred communicating with a node""。
def __init__(self, w3)。
msg = (
f "A web3 connection error occurred talking to"
f"{w3.provider.endpoint_uri}."。
)
super().__init__(msg)
self.w3 = w3
class NodeTooManyRequests(NodeError)。
def __init__(self, w3):
msg = (
f "向{w3.provider.endpoint_uri}發出的請求太多了。 嘗試一個"
f "不同的節點。"
)
super().__init__(msg)
self.w3 = w3
class NodeNoAvailableNodes(NodeError)。
def __init__(self):
msg = f "Unable to connect to any nodes." .
super().__init__(msg)
class NodeInternalError(NodeError)。
def __init__(self):
msg = "該節點有一個內部錯誤。"。
super().__init__(msg)
def lib_connect_to_node(url)。
""模擬庫連接到節點的功能""。
try。
w3 = Web3(
Web3.HTTPProvider(
網址。
request_kwargs={"timeout": 5}。
)
)
if not w3.isConnected()。
raise NodeNotConnected(url, w3)
except Exception as e:
raise NodeNotConnected(url) from e.
else:
return w3
def connect_to_node(urls, node_retries) 。
while node_retries >= 0:
try:
w3 = lib_connect_to_node(urls[0] )
except NodeNotConnected(urls[0]) as e:
if node_retries == 0:
raise NodeNoAvailableNodes from e
node_retries -=1
urls = get_next_node(urls)
print('Trying another node'/span>)
sleep(1)
繼續 繼續?
else:
return w3
def get_next_node(urls)。
urls.append(urls.pop(urls.index(urls[0] ))
return urls
def get_tx_count(w3, address)。
try:
nonce = w3.eth.get_transaction_count(address)
except (ConnectionError, ConnectTimeout) as e:
print("A requests.exceptions.ConnectionError occurred."/span>)
raise NodeConnectionError(w3) from e
except HTTPError as e:
if e.code == 429:
raise NodeTooManyRequests from e
else:
return nonce
def main()。
urls = [
'https://matic-mainnet-full-rpc.bwarelabs.com:443'。
'https://matic-mainnet.chainstacklabs.com:443'。
'https://rpc-mainnet.maticvigil.com:443'。
'https://rpc-mainnet.matic.network:443'.
]
node_retries = 3
地址 = '0xe18A0D121057B002BaFb90aD5F1AB951594A61E8'/span>
try:
w3 = connect_to_node(urls, node_retries)
except NodeNoAvailableNodes as e:
print(e)
sys.exit()
while True:
try:
print(get_tx_count(w3, address) )
sleep(0.05)
exceptNodeNotConnected(w3.provider.endpoint_uri, w3)。
urls = get_next_node(urls)
try:
w3 = connect_to_node(urls, node_retries)
except NodeNoAvailableNodes as e:
print(e)
sys.exit()
except NodeConnectionError(w3) ase:
urls = get_next_node(urls)
try:
w3 = connect_to_node(urls, node_retries)
except NodeNoAvailableNodes as e:
print(e)
sys.exit()
except NodeTooManyRequests(w3) as e:
print('Too many requests')
urls = get_next_node(urls)
try:
w3 = connect_to_node(urls, node_retries)
except NodeNoAvailableNodes as e:
print(e)
sys.exit()
if __name__ == '__main__'/span>:
main()
uj5u.com熱心網友回復:
你應該能夠捕捉到任何屬于例外的東西,即使它沒有直接繼承自BaseException。
然而,從except子句中洗掉類的引數,只保留類的名字:
try:
raise NodeNotConnected('abc'/span>)
except NodeNotConnected as e:
print(e)
結果:
A web3 connection could not be made to URL abc.
當你指定類的引數時,一個類被實體化了,它被評估為一個實體而不是一個型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/331107.html
標籤:
