diff --git a/CHANGELOG.md b/CHANGELOG.md
index befdf6dd5a2034cd620e92490ee52197b352fce2..327ab9f4b9cf9b23cd30dd7245279fcec68788a3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +1,4 @@
 # v2.7.18
+
+* reformatted `ProcessFailed` exception
+* added an option not to check the return code
\ No newline at end of file
diff --git a/satella/__init__.py b/satella/__init__.py
index fa287e484979e19a7d23db215c3e6b70c675e73a..6806d01093fc5bd00981f5ea99f1828b72679739 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.7.18_a1'
+__version__ = '2.7.18'
diff --git a/satella/exceptions.py b/satella/exceptions.py
index 320f13d062cb3945952b9aedd5382b35a788b144..5830784f5744c93165e1a224b3763b2d1218eaf6 100644
--- a/satella/exceptions.py
+++ b/satella/exceptions.py
@@ -162,8 +162,16 @@ class LockIsHeld(ResourceLocked):
 
 
 class ProcessFailed(BaseSatellaError):
-    """A process finished with other result code that it was requested"""
+    """A process finished with other result code that it was requested
 
-    def __init__(self, rc: int):
-        super().__init__(rc)
+    :param rc: return code of the process
+    :param stdout_so_far: process' stdout gathered so far
+    """
+
+    def __init__(self, rc: int, stdout_so_far: tp.Union[bytes, str]):
+        super().__init__(rc, stdout_so_far)
         self.rc = rc
+        self.stdout_so_far = stdout_so_far
+
+    def __str__(self):
+        return 'ProcessFailed(%s)' % (self.rc, )
diff --git a/satella/processes.py b/satella/processes.py
index eea97a3a1614f0121ccce123ad8c397a3a2b26c4..6ae160b4d66aa1d6d9bed2b66b837adb66717e98 100644
--- a/satella/processes.py
+++ b/satella/processes.py
@@ -22,7 +22,8 @@ def read_nowait(process: subprocess.Popen, output_list: tp.List[str]):
 def call_and_return_stdout(args: tp.Union[str, tp.List[str]],
                            timeout: tp.Optional[int] = None,
                            encoding: tp.Optional[str] = None,
-                           expected_return_code: int = 0, **kwargs) -> tp.Union[bytes, str]:
+                           expected_return_code: tp.Optional[int] = None,
+                           **kwargs) -> tp.Union[bytes, str]:
     """
     Call a process and return it's stdout.
 
@@ -36,7 +37,8 @@ def call_and_return_stdout(args: tp.Union[str, tp.List[str]],
         within this time, it will be sent a SIGKILL
     :param encoding: encoding with which to decode stdout. If none is passed, it will be returned as a bytes object
     :param expected_return_code: an expected return code of this process. 0 is the default. If process
-        returns anything else, ProcessFailed will be raise
+        returns anything else, ProcessFailed will be raise. If left default (None) return code won't be checked
+        at all
     :raises ProcessFailed: process' result code was different from the requested
     """
     if isinstance(args, str):
@@ -56,13 +58,14 @@ def call_and_return_stdout(args: tp.Union[str, tp.List[str]],
         proc.wait()
     reader_thread.join()
 
-    if proc.returncode != expected_return_code:
-        raise ProcessFailed(proc.returncode)
+    if encoding is None:
+        result = b''.join(stdout_list)
     else:
-        if encoding is None:
-            return b''.join(stdout_list)
-        else:
+        result = ''.join((row.decode(encoding) for row in stdout_list))
 
-            return ''.join((row.decode(encoding) for row in stdout_list))
+    if expected_return_code is not None:
+        if proc.returncode != expected_return_code:
+            raise ProcessFailed(proc.returncode, result)
 
+    return result
 
diff --git a/tests/test_processes.py b/tests/test_processes.py
index 533fcdb3a5b0f2f35c28917d86ed48b2b3070841..f53dc142bae569c8f7bf64b1467022603ea48bfb 100644
--- a/tests/test_processes.py
+++ b/tests/test_processes.py
@@ -6,7 +6,7 @@ from satella.processes import call_and_return_stdout
 class TestProcesses(unittest.TestCase):
     @unittest.skipIf('win' in sys.platform, 'Running on Windows')
     def test_return_stdout(self):
-        output = call_and_return_stdout('ls .', shell=True, timeout=3)
+        output = call_and_return_stdout('ls .', shell=True, timeout=3, expected_return_code=0)
         self.assertIn(b'requirements.txt', output)
 
     @unittest.skipIf('win' in sys.platform or sys.version_info.minor < 6, 'Running on Windows or Python 3.5')