Error handling in python with ldap - python

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))

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).

pysmb listpath method return error "SMB connection not authenticated"

I'm using pysmb to connect a server (192.168.1.54) the code are:
host = '192.168.1.54' # server IP
username = 'Test'
password = 'test'
my_name = "localmac"
remote_name = "servermac"
try:
conn = SMBConnection(username, password, my_name, remote_name, is_direct_tcp=True)
except Exception as e:
print (e)
return
try:
conn.connect(host,445) #
except Exception as e:
print (e)
return
bytedata = 'hello'.encode()
print(conn.echo(bytedata, timeout=10))
print(conn.is_using_smb2)
for i in conn.listPath('misc', ''):
print(i.filename, i.create_time)
the two 'print' codes run smoothly and the listPath function returned the error "SMB connection not authenticated". Why? if not authenticated, why the echo sentence didn't return error?
Any comments or helps are appreciated!
1) If you are sure that the username and password correct, check the version of pysmb.
I had similar problem with pysmb==1.2.6, so if you're using this version too, update to 1.2.8.
The problem was with pysmb's own implementation of MD4 algorithm.
When there is no MD4 in Python's hashlib pysmb uses its own algorithm:
try:
import hashlib
hashlib.new('md4')
def MD4(): return hashlib.new('md4')
except ( ImportError, ValueError ):
from .utils.md4 import MD4
So if it possible update to pysmb==1.2.8 where this problem was fixed.
2) if not authenticated, why the echo sentence didn't return error?
The echo command does not require authentication, it just sends data to the remote server and remote server replies with the same data.

urllib request fails when page takes too long to respond

I have a simple function (in python 3) to take a url and attempt to resolve it: printing an error code if there is one (e.g. 404) or resolve one of the shortened urls to its full url. My urls are in one column of a csv files and the output is saved in the next column. The problem arises where the program encounters a url where the server takes too long to respond- the program just crashes. Is there a simple way to force urllib to print an error code if the server is taking too long. I looked into Timeout on a function call but that looks a little too complicated as i am just starting out. Any suggestions?
i.e. (COL A) shorturl (COL B) http://deals.ebay.com/500276625
def urlparse(urlColumnElem):
try:
conn = urllib.request.urlopen(urlColumnElem)
except urllib.error.HTTPError as e:
return (e.code)
except urllib.error.URLError as e:
return ('URL_Error')
else:
redirect=conn.geturl()
#check redirect
if(redirect == urlColumnElem):
#print ("same: ")
#print(redirect)
return (redirect)
else:
#print("Not the same url ")
return(redirect)
EDIT: if anyone gets the http.client.disconnected error (like me), see this question/answer http.client.RemoteDisconnected error while reading/parsing a list of URL's
Have a look at the docs:
urllib.request.urlopen(url, data=None[, timeout])
The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used).
You can set a realistic timeout (in seconds) for your process:
conn = urllib.request.urlopen(urlColumnElem, timeout=realistic_timeout_in_seconds)
and in order for your code to stop crushing, move everything inside the try except block:
import socket
def urlparse(urlColumnElem):
try:
conn = urllib.request.urlopen(
urlColumnElem,
timeout=realistic_timeout_in_seconds
)
redirect=conn.geturl()
#check redirect
if(redirect == urlColumnElem):
#print ("same: ")
#print(redirect)
return (redirect)
else:
#print("Not the same url ")
return(redirect)
except urllib.error.HTTPError as e:
return (e.code)
except urllib.error.URLError as e:
return ('URL_Error')
except socket.timeout as e:
return ('Connection timeout')
Now if a timeout occurs, you will catch the exception and the program will not crush.
Good luck :)
First, there is a timeout parameter than can be used to control the time allowed for urlopen. Next an timeout in urlopen should just throw an exception, more precisely a socket.timeout. If you do not want it to abort the program, you just have to catch it:
def urlparse(urlColumnElem, timeout=5): # allow 5 seconds by default
try:
conn = urllib.request.urlopen(urlColumnElem, timeout = timeout)
except urllib.error.HTTPError as e:
return (e.code)
except urllib.error.URLError as e:
return ('URL_Error')
except socket.timeout:
return ('Timeout')
else:
...

In Python, how does one try (and except) the instantiation of a class?

In Python, how does one try/except the instantiation of a class?
For example, I'm working on a GitHub script at the moment:
from github3 import login
user = login(username, password)
At first, I thought it would be as easy as:
try:
user = login(username, password)
except Exception, e:
print e
However if I force an exception (e.g. provide the wrong arguments), then I don't see any exceptions:
$ python my-script.py -u 1 -p 1; echo $?
name 'pw' is not defined
0
If I try again, but take the try/except out of the mix, I get the exception I expect to see:
$ python my-script.py -u username -p password; echo $?
Traceback (most recent call last):
File "delete-all-gists.py", line 19, in <module>
user = login(u, pw)
NameError: name 'pw' is not defined
1
I can't be the only person who's asked this question, but I'm afraid my SO-search-fu may be failing me...
Update
Indeed, as mentioned in the comments, I appear to have had my eyes closed when asking this...
I think what was throwing me was that github3's login() method was not throwing any sort of exception if the wrong username/password was provided. For example:
from github3 import login
u = 'foo'
p = 'bar'
try:
user = login(u, p)
except Exception, e:
print e
Returns:
Nothing. No error, exception or anything.
However, the following does indeed raise an exception, as expected:
from github3 import login
u = 'foo'
p = 'bar'
try:
user = login(username, p)
except Exception, e:
print e
Returns:
name 'username' is not defined
Which is, of course, because I purposely provided a non-existent variable as the username parameter to the login() method to force an exception to be raised.
Remember that any time you run a try/except block it should be because you can REASONABLY HANDLE the exception that occurs. For instance:
username, password = input("Username: "), input("Password: ")
while True:
try:
login(username, password)
except BadPasswordException as e:
print("Invalid login")
else:
# you only get here if there are no exceptions
break
If you cannot reasonably handle an exception, it's best to log it and let the program gracefully exit.
try:
foo(some,arguments)
except CthuluHasBeenReleasedException as e:
logging.fatal("Oh (old) god!")
sys.exit(1)

urllib2 exception handling with couchdb

I usually have a hard time nailing down how to handle urllib2 exceptions. So I'm still learning. Here is a scenario that I'd like some advice on.
I have a local couch db database. I want to know if the database exists. ie "127.0.0.1:5984/database". If it does not exist, and I can reach "127.0.0.1:5984", I want to know so I can create the new database.
Here are several cases I'm thinking about:
1) I could get a timeout.
2) my url is wrong in the sense that I fail to reach the database entirely ie I typed 127.0.4.1:5984/database but couchdb is on 127.0.0.1:5984
3) the database path "database" does not exist on the couch database.
So here some code I wrote to handle it:
What I do is test the response. If everything is fine I set db_exists to True. The only time I set db_exists to False is if I get a 404. Everything else just exits the program.
request = urllib2.Request(address)
try:
response = urllib2.urlopen(request)
except urllib2.URLError, e:
if hasattr(e, 'reason'):
print 'Failed to reach database'
print 'Reason: ', e.reason
sys.exit()
elif hasattr(e, 'code'):
if e.code == 404:
db_exists = False
else:
print 'Failed to reach database'
print 'Reason: ' + str(e)
sys.exit()
else:
try:
#I am expecting a json response. So make sure of it.
json.loads(response.read())
except:
print 'Failed to reach database at "' + address + '"'
sys.exit()
else:
db_exists = True
I am following the exception handling scheme layed out in URLlib2 The Missing Manual.
So basically my questions are...
1) Is this a clean, robust way to handle this?
2) is it common practice to sprinkle sys.exit() throughout code.
-Update-
Using couchdb-python:
main(db_url):
database = couchdb.Database(url=db_url)
try:
database.info()
except couchdb.http.ResourceNotFound, err:
print '"' + db_url + '" ' + err.message[0] + ', ' + err.message[1]
return
except couchdb.http.Unauthorized, err:
print err.message[1]
return
except couchdb.http.ServerError, err:
print err.message
return
except socket.error, err:
print str(err)
return
if __name__ == '__main__':
# note that id did not show it here, but db_url comes from an arg.
main(db_url)
I would argue that you're attacking this problem at too low a level. Why not use couchdb-python?
To answer your questions, 1) no it is not an especially clean way to do this. I would at least factor the code in your except block out into a method that extracts error types suitable for your application out of the urrlib2.URLError. For 2), no it is bad practice to call sys.exit() nearly all the time. Raise an appropriate exception. By default this will bubble up and halt the interpreter, just like your sys.exit() but with a traceback. Or, since your Couch client is a library, the exceptions can be handled at the application's discretion. Library code should never exit the interpreter.

Categories