diff --git a/modules/aum/browser.py b/modules/aum/browser.py
index 9524feaf..ca07da12 100644
--- a/modules/aum/browser.py
+++ b/modules/aum/browser.py
@@ -27,6 +27,7 @@ import urllib
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserUnavailable
from weboob.tools.json import json
+from weboob.capabilities.base import UserError
from weboob.capabilities.chat import ChatException, ChatMessage
from weboob.capabilities.messages import CantSendMessage
@@ -34,7 +35,7 @@ from weboob.capabilities.messages import CantSendMessage
__all__ = ['AuMBrowser']
-class AuMException(Exception):
+class AuMException(UserError):
ERRORS = {"0.0.0": "Bad signature",
"0.0.1": "Malformed request",
"0.0.2": "Not logged",
diff --git a/modules/francetelevisions/pages.py b/modules/francetelevisions/pages.py
index 52c1387a..551bc2f1 100644
--- a/modules/francetelevisions/pages.py
+++ b/modules/francetelevisions/pages.py
@@ -20,6 +20,7 @@
import datetime
import re
+from weboob.capabilities import UserError
from weboob.tools.capabilities.thumbnail import Thumbnail
from weboob.tools.browser import BasePage, BrokenPageError
@@ -69,7 +70,7 @@ class VideoPage(BasePage):
def on_loaded(self):
p = self.parser.select(self.document.getroot(), 'p.alert')
if len(p) > 0:
- raise Exception(p[0].text)
+ raise UserError(p[0].text)
def get_info_url(self):
try:
diff --git a/modules/nolifetv/pages/video.py b/modules/nolifetv/pages/video.py
index 8d7f80c1..2d71c5c8 100644
--- a/modules/nolifetv/pages/video.py
+++ b/modules/nolifetv/pages/video.py
@@ -21,7 +21,7 @@
from dateutil.parser import parse as parse_dt
import urllib
-from weboob.capabilities.base import NotAvailable
+from weboob.capabilities.base import NotAvailable, UserError
from weboob.tools.capabilities.thumbnail import Thumbnail
from weboob.tools.browser import BasePage, BrokenPageError
from weboob.tools.misc import to_unicode
@@ -32,7 +32,7 @@ from ..video import NolifeTVVideo
__all__ = ['VideoPage']
-class ForbiddenVideo(Exception):
+class ForbiddenVideo(UserError):
pass
diff --git a/modules/transilien/pages/departures.py b/modules/transilien/pages/departures.py
index 7461de05..9f494a73 100644
--- a/modules/transilien/pages/departures.py
+++ b/modules/transilien/pages/departures.py
@@ -19,6 +19,7 @@
import datetime
+from weboob.capabilities import UserError
from weboob.tools.misc import to_unicode
from weboob.tools.browser import BasePage, BrokenPageError
@@ -26,7 +27,7 @@ from weboob.tools.browser import BasePage, BrokenPageError
__all__ = ['StationNotFound', 'DeparturesPage']
-class StationNotFound(Exception):
+class StationNotFound(UserError):
pass
class DeparturesPage(BasePage):
diff --git a/weboob/capabilities/__init__.py b/weboob/capabilities/__init__.py
index 88b00a16..d5511377 100644
--- a/weboob/capabilities/__init__.py
+++ b/weboob/capabilities/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from .base import NotLoaded, NotAvailable, CapBaseObject, IBaseCap
+from .base import UserError, NotLoaded, NotAvailable, CapBaseObject, IBaseCap
-__all__ = ['NotLoaded', 'NotAvailable', 'CapBaseObject', 'IBaseCap']
+__all__ = ['UserError', 'NotLoaded', 'NotAvailable', 'CapBaseObject', 'IBaseCap']
diff --git a/weboob/capabilities/account.py b/weboob/capabilities/account.py
index d1ab9565..0c492d80 100644
--- a/weboob/capabilities/account.py
+++ b/weboob/capabilities/account.py
@@ -18,13 +18,13 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, StringField, Field
+from .base import IBaseCap, CapBaseObject, StringField, Field, UserError
__all__ = ['AccountRegisterError', 'Account', 'StatusField', 'ICapAccount']
-class AccountRegisterError(Exception):
+class AccountRegisterError(UserError):
"""
Raised when there is an error during registration.
"""
diff --git a/weboob/capabilities/bank.py b/weboob/capabilities/bank.py
index 3db49a4a..af3107a2 100644
--- a/weboob/capabilities/bank.py
+++ b/weboob/capabilities/bank.py
@@ -20,22 +20,22 @@
from datetime import date, datetime
-from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField
+from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField, UserError
from .collection import ICapCollection
__all__ = ['AccountNotFound', 'TransferError', 'Recipient', 'Account', 'Transaction', 'Transfer', 'ICapBank']
-class AccountNotFound(Exception):
+class AccountNotFound(UserError):
"""
Raised when an account is not found.
"""
def __init__(self, msg='Account not found'):
- Exception.__init__(self, msg)
+ UserError.__init__(self, msg)
-class TransferError(Exception):
+class TransferError(UserError):
"""
A transfer has failed.
"""
diff --git a/weboob/capabilities/base.py b/weboob/capabilities/base.py
index 1922a071..90f47b82 100644
--- a/weboob/capabilities/base.py
+++ b/weboob/capabilities/base.py
@@ -27,7 +27,7 @@ from weboob.tools.misc import to_unicode
from weboob.tools.ordereddict import OrderedDict
-__all__ = ['FieldNotFound', 'NotAvailable', 'NotLoaded', 'IBaseCap',
+__all__ = ['UserError', 'FieldNotFound', 'NotAvailable', 'NotLoaded', 'IBaseCap',
'Field', 'IntField', 'DecimalField', 'FloatField', 'StringField',
'BytesField', 'DateField', 'DeltaField', 'empty', 'CapBaseObject']
@@ -44,6 +44,12 @@ def empty(value):
return False
+class UserError(Exception):
+ """
+ Exception containing an error message for user.
+ """
+
+
class FieldNotFound(Exception):
"""
A field isn't found.
diff --git a/weboob/capabilities/bill.py b/weboob/capabilities/bill.py
index 16bd0052..272bac3e 100644
--- a/weboob/capabilities/bill.py
+++ b/weboob/capabilities/bill.py
@@ -17,27 +17,28 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see .
-from .base import CapBaseObject, StringField, DateField, DecimalField
+
+from .base import CapBaseObject, StringField, DateField, DecimalField, UserError
from .collection import ICapCollection
__all__ = ['SubscriptionNotFound', 'BillNotFound', 'Detail', 'Bill', 'Subscription', 'ICapBill']
-class SubscriptionNotFound(Exception):
+class SubscriptionNotFound(UserError):
"""
Raised when a subscription is not found.
"""
def __init__(self, msg='Subscription not found'):
- Exception.__init__(self, msg)
+ UserError.__init__(self, msg)
-class BillNotFound(Exception):
+class BillNotFound(UserError):
"""
Raised when a bill is not found.
"""
def __init__(self, msg='Bill not found'):
- Exception.__init__(self, msg)
+ UserError.__init__(self, msg)
class Detail(CapBaseObject):
diff --git a/weboob/capabilities/bugtracker.py b/weboob/capabilities/bugtracker.py
index 7a752ba5..71a44e1d 100644
--- a/weboob/capabilities/bugtracker.py
+++ b/weboob/capabilities/bugtracker.py
@@ -19,14 +19,14 @@
from .base import IBaseCap, CapBaseObject, Field, StringField, DateField, \
- IntField, DeltaField
+ IntField, DeltaField, UserError
__all__ = ['IssueError', 'Project', 'User', 'Version', 'Status', 'Attachment',
'Change', 'Update', 'Issue', 'Query', 'ICapBugTracker']
-class IssueError(Exception):
+class IssueError(UserError):
"""
Raised when there is an error with an issue.
"""
diff --git a/weboob/capabilities/chat.py b/weboob/capabilities/chat.py
index 2b81ba20..dd585be4 100644
--- a/weboob/capabilities/chat.py
+++ b/weboob/capabilities/chat.py
@@ -20,13 +20,13 @@
import datetime
-from .base import IBaseCap, CapBaseObject, StringField, DateField
+from .base import IBaseCap, CapBaseObject, StringField, DateField, UserError
__all__ = ['ChatException', 'ChatMessage', 'ICapChat']
-class ChatException(Exception):
+class ChatException(UserError):
"""
Exception raised when there is a problem with the chat.
"""
diff --git a/weboob/capabilities/collection.py b/weboob/capabilities/collection.py
index 51cfe5e0..f7548136 100644
--- a/weboob/capabilities/collection.py
+++ b/weboob/capabilities/collection.py
@@ -17,18 +17,20 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject
+
+from .base import IBaseCap, CapBaseObject, UserError
+
__all__ = ['ICapCollection', 'BaseCollection', 'Collection', 'CollectionNotFound']
-class CollectionNotFound(Exception):
+class CollectionNotFound(UserError):
def __init__(self, split_path=None):
if split_path is not None:
msg = 'Collection not found: %s' % '/'.join(split_path)
else:
msg = 'Collection not found'
- Exception.__init__(self, msg)
+ UserError.__init__(self, msg)
class BaseCollection(CapBaseObject):
diff --git a/weboob/capabilities/contact.py b/weboob/capabilities/contact.py
index 6c738558..d057b491 100644
--- a/weboob/capabilities/contact.py
+++ b/weboob/capabilities/contact.py
@@ -18,7 +18,8 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, Field, StringField, BytesField, IntField
+from .base import IBaseCap, CapBaseObject, Field, StringField, BytesField, IntField, \
+ UserError
from weboob.tools.ordereddict import OrderedDict
@@ -108,7 +109,7 @@ class Contact(CapBaseObject):
setattr(photo, key, value)
-class QueryError(Exception):
+class QueryError(UserError):
"""
Raised when unable to send a query to a contact.
"""
diff --git a/weboob/capabilities/dating.py b/weboob/capabilities/dating.py
index 895f6f73..ff934cac 100644
--- a/weboob/capabilities/dating.py
+++ b/weboob/capabilities/dating.py
@@ -18,14 +18,14 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, Field, StringField, DateField
+from .base import IBaseCap, CapBaseObject, Field, StringField, DateField, UserError
from .contact import Contact
__all__ = ['OptimizationNotFound', 'Optimization', 'Event', 'ICapDating']
-class OptimizationNotFound(Exception):
+class OptimizationNotFound(UserError):
"""
Raised when an optimization is not found.
"""
diff --git a/weboob/capabilities/messages.py b/weboob/capabilities/messages.py
index 5ba0ce75..711875df 100644
--- a/weboob/capabilities/messages.py
+++ b/weboob/capabilities/messages.py
@@ -21,7 +21,8 @@
import datetime
import time
-from .base import IBaseCap, CapBaseObject, NotLoaded, Field, StringField, DateField, IntField
+from .base import IBaseCap, CapBaseObject, NotLoaded, Field, StringField, \
+ DateField, IntField, UserError
__all__ = ['Thread', 'Message', 'ICapMessages', 'CantSendMessage', 'ICapMessagesPost']
@@ -198,7 +199,7 @@ class ICapMessages(IBaseCap):
"""
raise NotImplementedError()
-class CantSendMessage(Exception):
+class CantSendMessage(UserError):
"""
Raised when a message can't be send.
"""
diff --git a/weboob/capabilities/paste.py b/weboob/capabilities/paste.py
index 4bdb352f..f8b9ef6d 100644
--- a/weboob/capabilities/paste.py
+++ b/weboob/capabilities/paste.py
@@ -18,13 +18,13 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, NotLoaded, Field, StringField
+from .base import IBaseCap, CapBaseObject, NotLoaded, Field, StringField, UserError
__all__ = ['PasteNotFound', 'BasePaste', 'ICapPaste']
-class PasteNotFound(Exception):
+class PasteNotFound(UserError):
"""
Raised when a paste is not found.
"""
diff --git a/weboob/capabilities/torrent.py b/weboob/capabilities/torrent.py
index 7f128aec..04ba5149 100644
--- a/weboob/capabilities/torrent.py
+++ b/weboob/capabilities/torrent.py
@@ -18,19 +18,20 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, Field, StringField, FloatField, DateField, IntField
+from .base import IBaseCap, CapBaseObject, Field, StringField, FloatField, \
+ DateField, IntField, UserError
__all__ = ['MagnetOnly', 'Torrent', 'ICapTorrent']
-class MagnetOnly(Exception):
+class MagnetOnly(UserError):
"""
Raised when trying to get URL to torrent but only magnet is available.
"""
def __init__(self, magnet):
self.magnet = magnet
- Exception.__init__(self, 'Only magnet URL is available')
+ UserError.__init__(self, 'Only magnet URL is available')
class Torrent(CapBaseObject):
diff --git a/weboob/capabilities/translate.py b/weboob/capabilities/translate.py
index e09ed8e2..470d29f2 100644
--- a/weboob/capabilities/translate.py
+++ b/weboob/capabilities/translate.py
@@ -18,28 +18,28 @@
# along with weboob. If not, see .
-from .base import IBaseCap, CapBaseObject, StringField
+from .base import IBaseCap, CapBaseObject, StringField, UserError
__all__ = ['TranslationFail', 'LanguageNotSupported', 'ICapTranslate']
-class LanguageNotSupported(Exception):
+class LanguageNotSupported(UserError):
"""
Raised when the language is not supported
"""
def __init__(self, msg='language is not supported'):
- Exception.__init__(self,msg)
+ UserError.__init__(self,msg)
-class TranslationFail(Exception):
+class TranslationFail(UserError):
"""
Raised when no translation matches the given request
"""
def __init__(self, msg='No Translation Available'):
- Exception.__init__(self, msg)
+ UserError.__init__(self, msg)
class Translation(CapBaseObject):
diff --git a/weboob/capabilities/travel.py b/weboob/capabilities/travel.py
index 5c16822b..73fde9c1 100644
--- a/weboob/capabilities/travel.py
+++ b/weboob/capabilities/travel.py
@@ -20,7 +20,8 @@
import datetime
-from .base import IBaseCap, CapBaseObject, StringField, TimeField, DeltaField, DateField
+from .base import IBaseCap, CapBaseObject, StringField, TimeField, DeltaField, \
+ DateField, UserError
__all__ = ['Station', 'Departure', 'RoadStep', 'RoadmapError', 'RoadmapFilters', 'ICapTravel']
@@ -72,7 +73,7 @@ class RoadStep(CapBaseObject):
arrival = StringField('Arrival station')
duration = DeltaField('Duration of this step')
-class RoadmapError(Exception):
+class RoadmapError(UserError):
"""
Raised when the roadmap is unable to be calculated.
"""
diff --git a/weboob/capabilities/weather.py b/weboob/capabilities/weather.py
index 4213dc2e..f5872656 100644
--- a/weboob/capabilities/weather.py
+++ b/weboob/capabilities/weather.py
@@ -20,7 +20,8 @@
from datetime import datetime
-from .base import IBaseCap, CapBaseObject, Field, DateField, FloatField, StringField
+from .base import IBaseCap, CapBaseObject, Field, DateField, FloatField, \
+ StringField, UserError
__all__ = ['Forecast', 'Current', 'City', 'CityNotFound', 'ICapWeather']
@@ -70,7 +71,7 @@ class City(CapBaseObject):
CapBaseObject.__init__(self, id)
self.name = name
-class CityNotFound(Exception):
+class CityNotFound(UserError):
"""
Raised when a city is not found.
"""
diff --git a/weboob/tools/application/qt/qt.py b/weboob/tools/application/qt/qt.py
index fbcfc526..24bbf597 100644
--- a/weboob/tools/application/qt/qt.py
+++ b/weboob/tools/application/qt/qt.py
@@ -34,6 +34,7 @@ from weboob.core.scheduler import IScheduler
from weboob.tools.browser import BrowserUnavailable, BrowserIncorrectPassword
from weboob.tools.value import ValueInt, ValueBool, ValueBackendPassword
from weboob.tools.misc import to_unicode
+from weboob.capabilities import UserError
from ..base import BaseApplication
@@ -173,10 +174,13 @@ class QtDo(QObject):
msg = 'Invalid login/password.'
elif isinstance(error, BrowserUnavailable):
if not msg:
- msg = 'website is unavailable.'
+ msg = 'Website is unavailable.'
elif isinstance(error, NotImplementedError):
msg = 'This feature is not supported by this backend.\n\n' \
'To help the maintainer of this backend implement this feature, please contact: %s <%s>' % (backend.MAINTAINER, backend.EMAIL)
+ elif isinstance(error, UserError):
+ if not msg:
+ msg = type(error).__name__
elif logging.root.level == logging.DEBUG:
msg += u'
'
ul_opened = False