Error handling Telegram bot - python

I am trying to avoid a telegram error. This error occurs when a message is not modified:
telegram.error.BadRequest: Message is not modified
I would like to make a function to print a message when this error occurs instead the original error message telegram prints. I have tried something like this but does not work:
def error_callback(bot, update, error):
try:
raise error
except BadRequest:
# handle malformed requests - read more below!
print('Same message')

First of all, if there are no evident bugs, this error could be happen if a user if clicking too fast on a button. In this case it can be easily ignored.
Assuming you are using python-telegram-bot library looking at your code, you can follow 2 approaches:
1. Ignore the error globally:
def error(bot, update, error):
if not (error.message == "Message is not modified"):
logger.warning('Update "%s" caused error "%s"' % (update, error))
but you will still receive on the console:
2017-11-03 17:16:41,405 - telegram.ext.dispatcher - WARNING - A TelegramError was raised while processing the Update
the only thing you can do is to disable that string for any error of any type doing this:
updater.dispatcher.logger.addFilter((lambda s: not s.msg.endswith('A TelegramError was raised while processing the Update')))
in your main(). credits
2. Ignore the error in the method you are calling:
You can ignore the error in the method you are calling doing:
try:
# the method causing the error
except TelegramError as e:
if str(e) != "Message is not modified": print(e)
This second approach will ignore the error completely on the console without modifying the error callback function, but you have to use it in every single method causing that exception.
Printing 'text' instead of ignoring:
i suggest you to ignore the error, but if you want to print a string as you said: you can very easily modify those 2 approaches to print the string.
Example for the first approach:
def error(bot, update, error):
if error.message == "Message is not modified":
# print your string
return
logger.warning('Update "%s" caused error "%s"' % (update, error))
Example of the second approach:
try:
# the method causing the error
except TelegramError as e:
if str(e) == "Message is not modified": print(your_string)

Related

Python script stops at error instead of carrying on

I am using Telethon for a telegram bot.
I've got a list of phone numbers. If the phone number is valid then to run a script, if it is invalid I want it to check another number.
This is the part of script which is causing me issues.
from telethon.sync import TelegramClient
from telethon.errors.rpcerrorlist import PhoneNumberBannedError
api_id = xxx # Your api_id
api_hash = 'xxx' # Your api_hash
try:
c = TelegramClient('{number}', api_id, api_hash)
c.start(number)
print('Login successful')
c.disconnect()
break
except ValueError:
print('invalid number')
If the number is invalud then I would expect the script to print 'invalid number' and then carry on. Except it is throwing error 'telethon.errors.rpcerrorlist.PhoneNumberInvalidError: The phone number is invalid (caused by SendCodeRequest)', then ending the script.
How can I carry on the script when this error is thrown?
Thanks
The exception you're catching is ValueError, but the error being thrown is telethon.errors.rpcerrorlist.PhoneNumberInvalidError.
So you need to catch that exception instead:
from telethon.errors.rpcerrorlist import PhoneNumberInvalidError
try:
# your code
except PhoneNumberInvalidError:
print('invalid number')
You can also combine error types if needed:
except (PhoneNumberInvalidError, ValueError):
# handle these types the same way
except TypeError:
# or add another 'except <type>' line to handle this error separately
This is especially useful when you're running a lot of code in your try and so a lot of different errors could occur.
Your last options is to catch every error using
try:
# code
except Exception:
print("exception!")
and while this might seem to be useful it will make debugging a lot harder as this will catch ANY error (which can easily hide unexpected errors) or it will handle them in the wrong way (you don't want to print 'invalid number' if it was actually a TypeError or KeyboardInterrupt for example).

Minio minio.error.SignatureDoesNotMatch thrown with try-except

I am using the python package for the minio server. I have the following piece of code that is used for a login:
from minio.error import [...], SignatureDoesNotMatch, [...]
def login(self):
try:
self.user = Minio(MINIO_CONFIG['MINIO_ENDPOINT'],
access_key=self.username,
secret_key=self.password,
secure=MINIO_CONFIG['MINIO_SECURE'])
return {"msg":"User is now logged in", "status": "OK"}
except SignatureDoesNotMatch as err:
return {"msg": err.message, "status":"F"}
except ResponseError as err:
return {'msg': err.message, 'status': "F"}
except InvalidAccessKeyId as err:
return {"msg": err.message, "status":"F"}
except InvalidArgument as err:
return {"msg": err.message, "status":"F"}
except InvalidArgumentError as err:
return {"msg": err.message, "status":"F"}
The issue I am facing is that even though I do have in the try-except the SignatureDoesNotMatch in case the credentials are not correct, it does not return me the msg it should but it throws an minio.error.SignatureDoesNotMatch instead. Why does that happen?
The error I get:
minio.error.SignatureDoesNotMatch: SignatureDoesNotMatch: message: The request signature we calculated does not match the signature you provided.
This seems fine, looking at the code, this will never run into an error on it's own, regardless of the credentials provided. It will only run into an error when it makes an API call, or when you invoke methods like list_buckets, list_objects etc using this self.user instance, from outside this block.
I think what you're trying to do is-- invoking methods like list_buckets etc from outside this encapsulation-- somewhere else not this part of the code, and then they produce this error and propagate them to the console. You cannot encapsulate the MinIO instance within try-catch and catch errors while you make use of stuff like self.user.list_buckets() from outside this try-catch block.

Client Error Exception's message in try except case

Hey I know I can do try except to resolve ClientError warning but is there any way that exception could be more precise meaning instead of except ClientError: Can I do except InvalidPermission.Duplicate:
This is the complete output I am getting without applying any exceptions:
botocore.exceptions.ClientError: An error occurred (InvalidPermission.Duplicate)
You can get error code like this -
using this-
try:
boto3_api_operation()
except ClientError as e:
code = e.response["Error"]["Code"]
print(code)
#O/p - InvalidPermission.Duplicate
You can read AWS Error Codes Documentation
Let me know,if it helps!

Error handling in python with ldap

I have this bit of code below, it is part of a python script iv been working on(piecing it together blocks at a time as learning curve). This bit binds to an ldap directory to query, so the rest of the script can to the queries.
When successful, it will print the below message in the block. When not successful it will throw an error- or at least i want to control the error.
If im not domain bound/vpn it will throw this message:
{'desc': "Can't contact LDAP server"}
if incorrect credentials :
Invalid credentials
nowhere in my script is it defined for the error message, how can i find where its fetching what to print that messsage- and possibly create or customize it?
(for what its worth i am using PyCharm)
try:
l = ldap.open(server)
l.simple_bind_s(user, pwd)
#if connection is successful print:
print "successfully bound to %s.\n" %server
l.protocol_version = ldap.VERSION3
except ldap.LDAPError, e:
print e
thanks
you can do something like this to provide a specific message for a specific exception.
try:
foo = 'hi'
bar = 'hello'
#do stuff
except ValueError:
raise ValueError("invalid credientials: {},{}".format(foo, bar))
so in your example it could become
except ldap.LDAPError:
raise ldap.LDAPError("invalid credientials: {},{}".format(user, pwd))
or if you literally just want to print it
except ldap.LDAPError:
print("invalid credientials: {},{}".format(user, pwd))

Python: Getting the error message of an exception

In python 2.6.6, how can I capture the error message of an exception.
IE:
response_dict = {} # contains info to response under a django view.
try:
plan.save()
response_dict.update({'plan_id': plan.id})
except IntegrityError, e: #contains my own custom exception raising with custom messages.
response_dict.update({'error': e})
return HttpResponse(json.dumps(response_dict), mimetype="application/json")
This doesnt seem to work. I get:
IntegrityError('Conflicts are not allowed.',) is not JSON serializable
Pass it through str() first.
response_dict.update({'error': str(e)})
Also note that certain exception classes may have specific attributes that give the exact error.
Everything about str is correct, yet another answer: an Exception instance has message attribute, and you may want to use it (if your customized IntegrityError doesn't do something special):
except IntegrityError, e: #contains my own custom exception raising with custom messages.
response_dict.update({'error': e.message})
You should use unicode instead of string if you are going to translate your application.
BTW, Im case you're using json because of an Ajax request, I suggest you to send errors back with HttpResponseServerError rather than HttpResponse:
from django.http import HttpResponse, HttpResponseServerError
response_dict = {} # contains info to response under a django view.
try:
plan.save()
response_dict.update({'plan_id': plan.id})
except IntegrityError, e: #contains my own custom exception raising with custom messages.
return HttpResponseServerError(unicode(e))
return HttpResponse(json.dumps(response_dict), mimetype="application/json")
and then manage errors in your Ajax procedure.
If you wish I can post some sample code.
Suppose you raise error like this
raise someError("some error message")
and 'e' is catched error instance
str(e) returns:
[ErrorDetail(string='some error message', code='invalid')]
but if you want "some error message" only
e.detail
will gives you that (actually gives you a list of str which includes "some error message")
This works for me:
def getExceptionMessageFromResponse( oResponse ):
#
'''
exception message is burried in the response object,
here is my struggle to get it out
'''
#
l = oResponse.__dict__['context']
#
oLast = l[-1]
#
dLast = oLast.dicts[-1]
#
return dLast.get( 'exception' )

Categories