dfb0848c84fbd2af50fabc6fb8c3d2907f843d65
[optf/osdf.git] / operation / error_handling.py
1 # -------------------------------------------------------------------------
2 #   Copyright (c) 2015-2017 AT&T Intellectual Property
3 #
4 #   Licensed under the Apache License, Version 2.0 (the "License");
5 #   you may not use this file except in compliance with the License.
6 #   You may obtain a copy of the License at
7 #
8 #       http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #   Unless required by applicable law or agreed to in writing, software
11 #   distributed under the License is distributed on an "AS IS" BASIS,
12 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 #   See the License for the specific language governing permissions and
14 #   limitations under the License.
15 #
16 # -------------------------------------------------------------------------
17 #
18
19 import json
20
21 from schematics.exceptions import DataError
22
23 from requests import RequestException
24 from requests import ConnectionError, HTTPError, Timeout
25 from osdf.operation.exceptions import BusinessException
26
27 import osdf
28
29 ERROR_TEMPLATE = osdf.ERROR_TEMPLATE
30
31 MESSAGE_BASE = "A solution couldn't be determined because an external application"
32 HTTP_ERROR_MESSAGE = MESSAGE_BASE + " returned a HTTP error"
33 TIMEOUT_ERROR_MESSAGE = MESSAGE_BASE + " could not respond in time, please check the external application"
34 CONNECTION_ERROR_MESSAGE = MESSAGE_BASE + " could not be reached"
35
36 internal_error_body = {
37         "serviceException": {
38             "text": "Unhandled internal exception, request could not be processed"
39         }
40 }
41
42 internal_error_message = json.dumps(internal_error_body)
43
44
45 def build_json_error_body(error):
46     if isinstance(error,RequestException):
47         return request_exception_to_json_body(error)
48     elif isinstance(error, DataError):
49         return data_error_to_json_body(error)
50     elif type(error) is BusinessException: # return the error message, because it is well formatted
51         return ERROR_TEMPLATE.render(description=str(error))
52     else:
53         return internal_error_message
54
55
56 def data_error_to_json_body(error):
57         description = str(error).replace('"', '\\"')
58         error_message = ERROR_TEMPLATE.render(description=description)
59         return error_message
60
61
62 def request_exception_to_json_body(error):
63     friendly_message = "A request exception has occurred when contacting an external system"
64     if type(error) is HTTPError:
65         friendly_message = HTTP_ERROR_MESSAGE
66     if type(error) is ConnectionError:
67         friendly_message = CONNECTION_ERROR_MESSAGE
68     if type(error) is Timeout:
69         friendly_message = TIMEOUT_ERROR_MESSAGE
70
71     eie_body = {
72             "serviceException": {
73                 "text": friendly_message,
74                 "errorType": "InterfaceError"
75             },
76             "externalApplicationDetails": {
77                 "httpMethod": error.request.method,
78                 "url": error.request.url
79             }
80     }
81
82     response = error.response
83
84     if response is not None:
85         eie_body['externalApplicationDetails']['httpStatusCode'] = response.status_code
86         content_type = response.headers.get('content-type')
87         if content_type is not None:
88             if 'application/json' in content_type:
89                 eie_body['externalApplicationDetails']['responseMessage'] = response.json()
90             elif 'text/html' in content_type:
91                 eie_body['externalApplicationDetails']['responseMessage'] = response.text
92     error_message = json.dumps(eie_body)
93     return error_message