Как мне перехватить все возможные ошибки с помощью url fetch (python)? - PullRequest
0 голосов
/ 06 марта 2011

В моем приложении пользователи вводят URL, и я пытаюсь открыть ссылку и получить заголовок страницы. Но я понял, что может быть много разных типов ошибок, в том числе символы юникода или новые строки в заголовках и AttributeError и IOError. Сначала я пытался перехватить каждую ошибку, но теперь в случае ошибки получения URL-адреса я хочу перенаправить на страницу с ошибкой, где пользователь вводит заголовок вручную. Как я могу поймать все возможные ошибки? Это код, который я сейчас имею:

    title = "title"

    try:

        soup = BeautifulSoup.BeautifulSoup(urllib.urlopen(url))
        title = str(soup.html.head.title.string)

        if title == "404 Not Found":
            self.redirect("/urlparseerror")
        elif title == "403 - Forbidden":
            self.redirect("/urlparseerror")     
        else:
            title = str(soup.html.head.title.string).lstrip("\r\n").rstrip("\r\n")

    except UnicodeDecodeError:    
        self.redirect("/urlparseerror?error=UnicodeDecodeError")

    except AttributeError:        
        self.redirect("/urlparseerror?error=AttributeError")

    #https url:    
    except IOError:        
        self.redirect("/urlparseerror?error=IOError")


    #I tried this else clause to catch any other error
    #but it does not work
    #this is executed when none of the errors above is true:
    #
    #else:
    #    self.redirect("/urlparseerror?error=some-unknown-error-caught-by-else")

UPDATE

Как предложено @Wooble в комментариях, я добавил try...except при записи title в базу данных:

        try:
            new_item = Main(
                        ....
                        title = unicode(title, "utf-8"))

            new_item.put()

        except UnicodeDecodeError:    

            self.redirect("/urlparseerror?error=UnicodeDecodeError")

Это работает. Хотя символ вне диапазона — по-прежнему находится в title в соответствии с информацией журнала:

***title: 7.2. re — Regular expression operations — Python v2.7.1 documentation**

Знаете почему?

Ответы [ 2 ]

2 голосов
/ 06 марта 2011

Вы можете использовать исключительный тип верхнего уровня Exception, который будет перехватывать любое исключение, которое не было перехвачено ранее.

http://docs.python.org/library/exceptions.html#exception-hierarchy

try:

    soup = BeautifulSoup.BeautifulSoup(urllib.urlopen(url))
    title = str(soup.html.head.title.string)

    if title == "404 Not Found":
        self.redirect("/urlparseerror")
    elif title == "403 - Forbidden":
        self.redirect("/urlparseerror")     
    else:
        title = str(soup.html.head.title.string).lstrip("\r\n").rstrip("\r\n")

except UnicodeDecodeError:    
    self.redirect("/urlparseerror?error=UnicodeDecodeError")

except AttributeError:        
    self.redirect("/urlparseerror?error=AttributeError")

#https url:    
except IOError:        
    self.redirect("/urlparseerror?error=IOError")

except Exception, ex:
    print "Exception caught: %s" % ex.__class__.__name__
2 голосов
/ 06 марта 2011

Вы можете использовать, кроме как без указания какого-либо типа, чтобы перехватить все исключения.

Из документации по питону http://docs.python.org/tutorial/errors.html:

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

Последнее исключение будет перехватывать любое исключение, которое не было перехвачено ранее (то есть исключение, которое не относится к IOError или ValueError.)

...