Resolvi fazer um básico sobre Python, que ainda não domino completamente, mas de todas as linguagens que já vi, foi a que eu mais gostei, pois une poder a simplicidade.
Bom, vamos lá então.
O que é o tratamento de exceções?
Sem copiar textos de outros lugares, para entender o tratamento de exceções, precisamos entender o que é uma exceção dentro da programação.
Uma exceção é algo que saía fora do planejado, por exemplo, você querer somar dois números, mas acabar inserindo uma letra e um número, irá gerar um erro, esse erro é a chamada exceção. Exceções muitas vezes são feias, visualmente falando, e acabam trazendo informações desnecessárias ao usuário final e algumas vezes causam até o vazamento de informações.
O tratamento de exceções é basicamente filtrar esses erros "feios", que costumam apresentar informações mais técnicas, para ajudar o programador a encontrar o erro, e exibir somente uma mensagem mais amigável e talvez com apenas um código do erro.
Na prática...
Um script simples para somar 2 números:
python
>>>
N1 = 25
>>>
N2 = 'asd'
>>>
N1 + N2
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Essa:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'
É a exceção, que informa ali a linha onde ocorreu o erro e o tipo, isso é feio para o usuário e na maioria das vezes só vai confundi-lo, então vamos usar o chamado tratamento de exceções. Em
Python, assim como em muitas linguagens, ele é feito na sua forma mais básica com
try e
except.
Sua sintaxe é semelhante a muitas linguagens de alto de nível:
try:
comandos
except:
comandos que deverão ser executados caso de algo errado
Voltando a código ali de cima, vamos filtrar esse erro:
>>>
N1 = 25
>>>
N2 = 'asd'
>>>
try:
N1 + N2
except:
print('erro ao tentar realizar a soma')
Executando:
erro ao tentar realizar a soma
>>>
E já filtramos o erro, porém isso é muito vago, por que ocorreu o erro?
Para resolver isso, podemos criar exceções específicas para cada tipo de erro. O Python é bem gentil nessa parte e já te diz direto o tipo de erro. Voltando lá em cima no erro, qual o tipo de erro?
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'
TypeError! Então aí já sabemos o tipo do erro e podemos criar uma exceção específica pra erros desse tipo:
>>>
N1 = 25
>>>
N2 = 'asd'
>>>
try:
N1 + N2
except TypeError:
print('erro ao tentar realizar a soma, tipos de dados diferentes')
Executando:
erro ao tentar realizar a soma, tipos de dados diferentes
>>>
À primeira vista, parece ser a mesma coisa, usar except somente e except <tipo do erro>, mas para códigos maiores, onde existam possibilidades de tipos diferentes de erros, isso ajuda tanto o programador, quanto o usuário a terem uma ideia do que saiu errado.
Um exemplo genérico: dois erros comuns ao se trabalhar com urllib, um erro HTTP e um erro na URL:
>>>
url.urlopen('http://www.sitenaoexiste.com')
Traceback (most recent call last):
File "C:\Python34\lib\urllib\request.py", line 1174, in do_open
h.request(req.get_method(), req.selector, req.data, headers)
File "C:\Python34\lib\http\client.py", line 1090, in request
self._send_request(method, url, body, headers)
File "C:\Python34\lib\http\client.py", line 1128, in _send_request
self.endheaders(body)
File "C:\Python34\lib\http\client.py", line 1086, in endheaders
self._send_output(message_body)
File "C:\Python34\lib\http\client.py", line 924, in _send_output
self.send(msg)
File "C:\Python34\lib\http\client.py", line 859, in send
self.connect()
File "C:\Python34\lib\http\client.py", line 836, in connect
self.timeout, self.source_address)
File "C:\Python34\lib\socket.py", line 491, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "C:\Python34\lib\socket.py", line 530, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11004] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
url.urlopen('http://www.sitenaoexiste.com')
File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
return opener.open(url, data, timeout)
File "C:\Python34\lib\urllib\request.py", line 455, in open
response = self._open(req, data)
File "C:\Python34\lib\urllib\request.py", line 473, in _open
'_open', req)
File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
result = func(*args)
File "C:\Python34\lib\urllib\request.py", line 1202, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "C:\Python34\lib\urllib\request.py", line 1176, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 11004] getaddrinfo failed>
>>>
url.urlopen('http://www.webcheats.com.br')
Traceback (most recent call last):
File "<pyshell#62>", line 1, in <module>
url.urlopen('http://www.webcheats.com.br')
File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
return opener.open(url, data, timeout)
File "C:\Python34\lib\urllib\request.py", line 461, in open
response = meth(req, response)
File "C:\Python34\lib\urllib\request.py", line 571, in http_response
'http', request, response, code, msg, hdrs)
File "C:\Python34\lib\urllib\request.py", line 499, in error
return self._call_chain(*args)
File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
result = func(*args)
File "C:\Python34\lib\urllib\request.py", line 579, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
>>>
O primeiro erro é porque o site não existe, o segundo é porque o fórum bloqueia certas requisições, até onde eu vi, com base no user-agent, pois alterando o user-agent da minha requisição, consegui conectar (mas isso é assunto pra outra hora).
Se tentássemos usar o try, não saberíamos ao certo o que deu errado.
>>>
try:
url.urlopen('http://www.sitenaoexiste.com')
except:
print('erro')
erro
>>>
try:
url.urlopen('http://www.webcheats.com.br')
except:
print('erro')
erro
>>>
Já se tentarmos filtrar por tipo de erro:
>>>
try:
url.urlopen('http://www.sitenaoexiste.com')
except urllib.error.HTTPError:
print('Erro HTTP')
except urllib.error.URLError:
print('erro ao tentar abrir a URL')
erro ao tentar abrir a URL
>>>
try:
url.urlopen('http://www.webcheats.com.br')
except urllib.error.HTTPError:
print('Erro HTTP')
except urllib.error.URLError:
print('erro ao tentar abrir a URL')
Erro HTTP
>>>
Mas podemos dar ainda mais detalhes sobre o erro, de forma amigável, pegando o erro HTTP por exemplo, existem vários tipos: error 404, 403 etc, que são códigos que servem para dizer o que deu errado. Para quem quiser dar uma olhada nos códigos:
>>>
try:
url.urlopen('http://www.webcheats.com.br')
except urllib.error.HTTPError as errohttp:
print('Erro HTTP, código do erro: {code}' .format(code = errohttp.code))
except urllib.error.URLError:
print('erro ao tentar abrir a URL')
Erro HTTP, código do erro: 403
>>>
E é isso aí. :)
Fonte: