Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions fs/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from __future__ import unicode_literals
from __future__ import print_function

import functools

import six
from six import text_type

Expand Down Expand Up @@ -90,8 +92,24 @@ class CreateFailed(FSError):
"""Filesystem could not be created.
"""

default_message = "unable to create filesystem"

default_message = "unable to create filesystem, {details}"

@classmethod
def catch_all(cls, func):
@functools.wraps(func)
def new_func(*args, **kwargs):
try:
return func(*args, **kwargs)
except cls:
raise
except Exception as e:
raise cls(exc=e)
return new_func

def __init__(self, msg=None, exc=None):
self._msg = msg or self.default_message
self.details = '' if exc is None else text_type(exc)
self.exc = exc

class PathError(FSError):
"""Base exception for errors to do with a path string.
Expand Down
7 changes: 3 additions & 4 deletions fs/osfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,12 @@ def __init__(self,
os.makedirs(_root_path, mode=create_mode)
except OSError as error:
raise errors.CreateFailed(
'unable to create {} ({})'.format(root_path, error)
'unable to create {} ({})'.format(root_path, error),
error,
)
else:
if not os.path.isdir(_root_path):
raise errors.CreateFailed(
'root path does not exist'
)
raise errors.CreateFailed('root path does not exist')

_meta = self._meta = {
'case_insensitive': os.path.normcase('Aa') != 'aa',
Expand Down
1 change: 1 addition & 0 deletions fs/tarfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class ReadTarFS(FS):
tarfile.LNKTYPE: ResourceType.symlink,
}

@errors.CreateFailed.catch_all
def __init__(self, file, encoding='utf-8'):
super(ReadTarFS, self).__init__()
self._file = file
Expand Down
1 change: 1 addition & 0 deletions fs/zipfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ class ReadZipFS(FS):
'virtual': False,
}

@errors.CreateFailed.catch_all
def __init__(self, file, encoding='utf-8'):
super(ReadZipFS, self).__init__()
self._file = file
Expand Down
20 changes: 20 additions & 0 deletions tests/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from six import text_type

from fs import errors
from fs.errors import CreateFailed


class TestErrors(unittest.TestCase):
Expand All @@ -24,3 +25,22 @@ def test_unsupported(self):
text_type(err),
"not supported"
)


class TestCreateFailed(unittest.TestCase):

def test_catch_all(self):

errors = (ZeroDivisionError, ValueError, CreateFailed)

@CreateFailed.catch_all
def test(x):
raise errors[x]

for index, exc in enumerate(errors):
try:
test(index)
except Exception as e:
self.assertIsInstance(e, CreateFailed)
if e.exc is not None:
self.assertNotIsInstance(e.exc, CreateFailed)