prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Not a Contribution: create_api_error_from_api_exception should   "raise <exception> from <original-error>" to preserve error message
  Not a Contribution.
  
  APIError handling should be changed to so that it doesn't hide the original exception.
  
  https://stackoverflow.com/questions/24752395/python-raise-from-usage
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `docker/errors.py`
  Content:
  ```
  1 import requests
  2 
  3 
  4 class DockerException(Exception):
  5     """
  6     A base class from which all other exceptions inherit.
  7 
  8     If you want to catch all errors that the Docker SDK might raise,
  9     catch this base exception.
  10     """
  11 
  12 
  13 def create_api_error_from_http_exception(e):
  14     """
  15     Create a suitable APIError from requests.exceptions.HTTPError.
  16     """
  17     response = e.response
  18     try:
  19         explanation = response.json()['message']
  20     except ValueError:
  21         explanation = (response.content or '').strip()
  22     cls = APIError
  23     if response.status_code == 404:
  24         if explanation and ('No such image' in str(explanation) or
  25                             'not found: does not exist or no pull access'
  26                             in str(explanation) or
  27                             'repository does not exist' in str(explanation)):
  28             cls = ImageNotFound
  29         else:
  30             cls = NotFound
  31     raise cls(e, response=response, explanation=explanation)
  32 
  33 
  34 class APIError(requests.exceptions.HTTPError, DockerException):
  35     """
  36     An HTTP error from the API.
  37     """
  38     def __init__(self, message, response=None, explanation=None):
  39         # requests 1.2 supports response as a keyword argument, but
  40         # requests 1.1 doesn't
  41         super().__init__(message)
  42         self.response = response
  43         self.explanation = explanation
  44 
  45     def __str__(self):
  46         message = super().__str__()
  47 
  48         if self.is_client_error():
  49             message = '{} Client Error for {}: {}'.format(
  50                 self.response.status_code, self.response.url,
  51                 self.response.reason)
  52 
  53         elif self.is_server_error():
  54             message = '{} Server Error for {}: {}'.format(
  55                 self.response.status_code, self.response.url,
  56                 self.response.reason)
  57 
  58         if self.explanation:
  59             message = f'{message} ("{self.explanation}")'
  60 
  61         return message
  62 
  63     @property
  64     def status_code(self):
  65         if self.response is not None:
  66             return self.response.status_code
  67 
  68     def is_error(self):
  69         return self.is_client_error() or self.is_server_error()
  70 
  71     def is_client_error(self):
  72         if self.status_code is None:
  73             return False
  74         return 400 <= self.status_code < 500
  75 
  76     def is_server_error(self):
  77         if self.status_code is None:
  78             return False
  79         return 500 <= self.status_code < 600
  80 
  81 
  82 class NotFound(APIError):
  83     pass
  84 
  85 
  86 class ImageNotFound(NotFound):
  87     pass
  88 
  89 
  90 class InvalidVersion(DockerException):
  91     pass
  92 
  93 
  94 class InvalidRepository(DockerException):
  95     pass
  96 
  97 
  98 class InvalidConfigFile(DockerException):
  99     pass
  100 
  101 
  102 class InvalidArgument(DockerException):
  103     pass
  104 
  105 
  106 class DeprecatedMethod(DockerException):
  107     pass
  108 
  109 
  110 class TLSParameterError(DockerException):
  111     def __init__(self, msg):
  112         self.msg = msg
  113 
  114     def __str__(self):
  115         return self.msg + (". TLS configurations should map the Docker CLI "
  116                            "client configurations. See "
  117                            "https://docs.docker.com/engine/articles/https/ "
  118                            "for API details.")
  119 
  120 
  121 class NullResource(DockerException, ValueError):
  122     pass
  123 
  124 
  125 class ContainerError(DockerException):
  126     """
  127     Represents a container that has exited with a non-zero exit code.
  128     """
  129     def __init__(self, container, exit_status, command, image, stderr):
  130         self.container = container
  131         self.exit_status = exit_status
  132         self.command = command
  133         self.image = image
  134         self.stderr = stderr
  135 
  136         err = f": {stderr}" if stderr is not None else ""
  137         msg = ("Command '{}' in image '{}' returned non-zero exit "
  138                "status {}{}").format(command, image, exit_status, err)
  139 
  140         super().__init__(msg)
  141 
  142 
  143 class StreamParseError(RuntimeError):
  144     def __init__(self, reason):
  145         self.msg = reason
  146 
  147 
  148 class BuildError(DockerException):
  149     def __init__(self, reason, build_log):
  150         super().__init__(reason)
  151         self.msg = reason
  152         self.build_log = build_log
  153 
  154 
  155 class ImageLoadError(DockerException):
  156     pass
  157 
  158 
  159 def create_unexpected_kwargs_error(name, kwargs):
  160     quoted_kwargs = [f"'{k}'" for k in sorted(kwargs)]
  161     text = [f"{name}() "]
  162     if len(quoted_kwargs) == 1:
  163         text.append("got an unexpected keyword argument ")
  164     else:
  165         text.append("got unexpected keyword arguments ")
  166     text.append(', '.join(quoted_kwargs))
  167     return TypeError(''.join(text))
  168 
  169 
  170 class MissingContextParameter(DockerException):
  171     def __init__(self, param):
  172         self.param = param
  173 
  174     def __str__(self):
  175         return (f"missing parameter: {self.param}")
  176 
  177 
  178 class ContextAlreadyExists(DockerException):
  179     def __init__(self, name):
  180         self.name = name
  181 
  182     def __str__(self):
  183         return (f"context {self.name} already exists")
  184 
  185 
  186 class ContextException(DockerException):
  187     def __init__(self, msg):
  188         self.msg = msg
  189 
  190     def __str__(self):
  191         return (self.msg)
  192 
  193 
  194 class ContextNotFound(DockerException):
  195     def __init__(self, name):
  196         self.name = name
  197 
  198     def __str__(self):
  199         return (f"context '{self.name}' not found")
  200
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/docker/errors.py b/docker/errors.py
  --- a/docker/errors.py
  +++ b/docker/errors.py
  @@ -28,7 +28,7 @@
               cls = ImageNotFound
           else:
               cls = NotFound
  -    raise cls(e, response=response, explanation=explanation)
  +    raise cls(e, response=response, explanation=explanation) from e
   
   
   class APIError(requests.exceptions.HTTPError, DockerException):
  
verification_info: {"golden_diff": "diff --git a/docker/errors.py b/docker/errors.py\n--- a/docker/errors.py\n+++ b/docker/errors.py\n@@ -28,7 +28,7 @@\n             cls = ImageNotFound\n         else:\n             cls = NotFound\n-    raise cls(e, response=response, explanation=explanation)\n+    raise cls(e, response=response, explanation=explanation) from e\n \n \n class APIError(requests.exceptions.HTTPError, DockerException):\n", "issue": "Not a Contribution: create_api_error_from_api_exception should   \"raise <exception> from <original-error>\" to preserve error message\nNot a Contribution.\r\n\r\nAPIError handling should be changed to so that it doesn't hide the original exception.\r\n\r\nhttps://stackoverflow.com/questions/24752395/python-raise-from-usage\n", "before_files": [{"content": "import requests\n\n\nclass DockerException(Exception):\n    \"\"\"\n    A base class from which all other exceptions inherit.\n\n    If you want to catch all errors that the Docker SDK might raise,\n    catch this base exception.\n    \"\"\"\n\n\ndef create_api_error_from_http_exception(e):\n    \"\"\"\n    Create a suitable APIError from requests.exceptions.HTTPError.\n    \"\"\"\n    response = e.response\n    try:\n        explanation = response.json()['message']\n    except ValueError:\n        explanation = (response.content or '').strip()\n    cls = APIError\n    if response.status_code == 404:\n        if explanation and ('No such image' in str(explanation) or\n                            'not found: does not exist or no pull access'\n                            in str(explanation) or\n                            'repository does not exist' in str(explanation)):\n            cls = ImageNotFound\n        else:\n            cls = NotFound\n    raise cls(e, response=response, explanation=explanation)\n\n\nclass APIError(requests.exceptions.HTTPError, DockerException):\n    \"\"\"\n    An HTTP error from the API.\n    \"\"\"\n    def __init__(self, message, response=None, explanation=None):\n        # requests 1.2 supports response as a keyword argument, but\n        # requests 1.1 doesn't\n        super().__init__(message)\n        self.response = response\n        self.explanation = explanation\n\n    def __str__(self):\n        message = super().__str__()\n\n        if self.is_client_error():\n            message = '{} Client Error for {}: {}'.format(\n                self.response.status_code, self.response.url,\n                self.response.reason)\n\n        elif self.is_server_error():\n            message = '{} Server Error for {}: {}'.format(\n                self.response.status_code, self.response.url,\n                self.response.reason)\n\n        if self.explanation:\n            message = f'{message} (\"{self.explanation}\")'\n\n        return message\n\n    @property\n    def status_code(self):\n        if self.response is not None:\n            return self.response.status_code\n\n    def is_error(self):\n        return self.is_client_error() or self.is_server_error()\n\n    def is_client_error(self):\n        if self.status_code is None:\n            return False\n        return 400 <= self.status_code < 500\n\n    def is_server_error(self):\n        if self.status_code is None:\n            return False\n        return 500 <= self.status_code < 600\n\n\nclass NotFound(APIError):\n    pass\n\n\nclass ImageNotFound(NotFound):\n    pass\n\n\nclass InvalidVersion(DockerException):\n    pass\n\n\nclass InvalidRepository(DockerException):\n    pass\n\n\nclass InvalidConfigFile(DockerException):\n    pass\n\n\nclass InvalidArgument(DockerException):\n    pass\n\n\nclass DeprecatedMethod(DockerException):\n    pass\n\n\nclass TLSParameterError(DockerException):\n    def __init__(self, msg):\n        self.msg = msg\n\n    def __str__(self):\n        return self.msg + (\". TLS configurations should map the Docker CLI \"\n                           \"client configurations. See \"\n                           \"https://docs.docker.com/engine/articles/https/ \"\n                           \"for API details.\")\n\n\nclass NullResource(DockerException, ValueError):\n    pass\n\n\nclass ContainerError(DockerException):\n    \"\"\"\n    Represents a container that has exited with a non-zero exit code.\n    \"\"\"\n    def __init__(self, container, exit_status, command, image, stderr):\n        self.container = container\n        self.exit_status = exit_status\n        self.command = command\n        self.image = image\n        self.stderr = stderr\n\n        err = f\": {stderr}\" if stderr is not None else \"\"\n        msg = (\"Command '{}' in image '{}' returned non-zero exit \"\n               \"status {}{}\").format(command, image, exit_status, err)\n\n        super().__init__(msg)\n\n\nclass StreamParseError(RuntimeError):\n    def __init__(self, reason):\n        self.msg = reason\n\n\nclass BuildError(DockerException):\n    def __init__(self, reason, build_log):\n        super().__init__(reason)\n        self.msg = reason\n        self.build_log = build_log\n\n\nclass ImageLoadError(DockerException):\n    pass\n\n\ndef create_unexpected_kwargs_error(name, kwargs):\n    quoted_kwargs = [f\"'{k}'\" for k in sorted(kwargs)]\n    text = [f\"{name}() \"]\n    if len(quoted_kwargs) == 1:\n        text.append(\"got an unexpected keyword argument \")\n    else:\n        text.append(\"got unexpected keyword arguments \")\n    text.append(', '.join(quoted_kwargs))\n    return TypeError(''.join(text))\n\n\nclass MissingContextParameter(DockerException):\n    def __init__(self, param):\n        self.param = param\n\n    def __str__(self):\n        return (f\"missing parameter: {self.param}\")\n\n\nclass ContextAlreadyExists(DockerException):\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return (f\"context {self.name} already exists\")\n\n\nclass ContextException(DockerException):\n    def __init__(self, msg):\n        self.msg = msg\n\n    def __str__(self):\n        return (self.msg)\n\n\nclass ContextNotFound(DockerException):\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return (f\"context '{self.name}' not found\")\n", "path": "docker/errors.py"}], "after_files": [{"content": "import requests\n\n\nclass DockerException(Exception):\n    \"\"\"\n    A base class from which all other exceptions inherit.\n\n    If you want to catch all errors that the Docker SDK might raise,\n    catch this base exception.\n    \"\"\"\n\n\ndef create_api_error_from_http_exception(e):\n    \"\"\"\n    Create a suitable APIError from requests.exceptions.HTTPError.\n    \"\"\"\n    response = e.response\n    try:\n        explanation = response.json()['message']\n    except ValueError:\n        explanation = (response.content or '').strip()\n    cls = APIError\n    if response.status_code == 404:\n        if explanation and ('No such image' in str(explanation) or\n                            'not found: does not exist or no pull access'\n                            in str(explanation) or\n                            'repository does not exist' in str(explanation)):\n            cls = ImageNotFound\n        else:\n            cls = NotFound\n    raise cls(e, response=response, explanation=explanation) from e\n\n\nclass APIError(requests.exceptions.HTTPError, DockerException):\n    \"\"\"\n    An HTTP error from the API.\n    \"\"\"\n    def __init__(self, message, response=None, explanation=None):\n        # requests 1.2 supports response as a keyword argument, but\n        # requests 1.1 doesn't\n        super().__init__(message)\n        self.response = response\n        self.explanation = explanation\n\n    def __str__(self):\n        message = super().__str__()\n\n        if self.is_client_error():\n            message = '{} Client Error for {}: {}'.format(\n                self.response.status_code, self.response.url,\n                self.response.reason)\n\n        elif self.is_server_error():\n            message = '{} Server Error for {}: {}'.format(\n                self.response.status_code, self.response.url,\n                self.response.reason)\n\n        if self.explanation:\n            message = f'{message} (\"{self.explanation}\")'\n\n        return message\n\n    @property\n    def status_code(self):\n        if self.response is not None:\n            return self.response.status_code\n\n    def is_error(self):\n        return self.is_client_error() or self.is_server_error()\n\n    def is_client_error(self):\n        if self.status_code is None:\n            return False\n        return 400 <= self.status_code < 500\n\n    def is_server_error(self):\n        if self.status_code is None:\n            return False\n        return 500 <= self.status_code < 600\n\n\nclass NotFound(APIError):\n    pass\n\n\nclass ImageNotFound(NotFound):\n    pass\n\n\nclass InvalidVersion(DockerException):\n    pass\n\n\nclass InvalidRepository(DockerException):\n    pass\n\n\nclass InvalidConfigFile(DockerException):\n    pass\n\n\nclass InvalidArgument(DockerException):\n    pass\n\n\nclass DeprecatedMethod(DockerException):\n    pass\n\n\nclass TLSParameterError(DockerException):\n    def __init__(self, msg):\n        self.msg = msg\n\n    def __str__(self):\n        return self.msg + (\". TLS configurations should map the Docker CLI \"\n                           \"client configurations. See \"\n                           \"https://docs.docker.com/engine/articles/https/ \"\n                           \"for API details.\")\n\n\nclass NullResource(DockerException, ValueError):\n    pass\n\n\nclass ContainerError(DockerException):\n    \"\"\"\n    Represents a container that has exited with a non-zero exit code.\n    \"\"\"\n    def __init__(self, container, exit_status, command, image, stderr):\n        self.container = container\n        self.exit_status = exit_status\n        self.command = command\n        self.image = image\n        self.stderr = stderr\n\n        err = f\": {stderr}\" if stderr is not None else \"\"\n        msg = (\"Command '{}' in image '{}' returned non-zero exit \"\n               \"status {}{}\").format(command, image, exit_status, err)\n\n        super().__init__(msg)\n\n\nclass StreamParseError(RuntimeError):\n    def __init__(self, reason):\n        self.msg = reason\n\n\nclass BuildError(DockerException):\n    def __init__(self, reason, build_log):\n        super().__init__(reason)\n        self.msg = reason\n        self.build_log = build_log\n\n\nclass ImageLoadError(DockerException):\n    pass\n\n\ndef create_unexpected_kwargs_error(name, kwargs):\n    quoted_kwargs = [f\"'{k}'\" for k in sorted(kwargs)]\n    text = [f\"{name}() \"]\n    if len(quoted_kwargs) == 1:\n        text.append(\"got an unexpected keyword argument \")\n    else:\n        text.append(\"got unexpected keyword arguments \")\n    text.append(', '.join(quoted_kwargs))\n    return TypeError(''.join(text))\n\n\nclass MissingContextParameter(DockerException):\n    def __init__(self, param):\n        self.param = param\n\n    def __str__(self):\n        return (f\"missing parameter: {self.param}\")\n\n\nclass ContextAlreadyExists(DockerException):\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return (f\"context {self.name} already exists\")\n\n\nclass ContextException(DockerException):\n    def __init__(self, msg):\n        self.msg = msg\n\n    def __str__(self):\n        return (self.msg)\n\n\nclass ContextNotFound(DockerException):\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return (f\"context '{self.name}' not found\")\n", "path": "docker/errors.py"}]}