Skip to content

Commit 34d784a

Browse files
authored
Better error message (#837)
* add error handling for return code 163 * improve documentation * fix type error
1 parent e35262c commit 34d784a

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

openml/_api_calls.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import time
2+
from typing import Dict
23
import requests
34
import warnings
45

@@ -80,7 +81,7 @@ def _read_url_files(url, data=None, file_elements=None):
8081
files=file_elements,
8182
)
8283
if response.status_code != 200:
83-
raise _parse_server_exception(response, url)
84+
raise _parse_server_exception(response, url, file_elements=file_elements)
8485
if 'Content-Encoding' not in response.headers or \
8586
response.headers['Content-Encoding'] != 'gzip':
8687
warnings.warn('Received uncompressed content from OpenML for {}.'
@@ -95,7 +96,7 @@ def _read_url(url, request_method, data=None):
9596

9697
response = send_request(request_method=request_method, url=url, data=data)
9798
if response.status_code != 200:
98-
raise _parse_server_exception(response, url)
99+
raise _parse_server_exception(response, url, file_elements=None)
99100
if 'Content-Encoding' not in response.headers or \
100101
response.headers['Content-Encoding'] != 'gzip':
101102
warnings.warn('Received uncompressed content from OpenML for {}.'
@@ -137,7 +138,11 @@ def send_request(
137138
return response
138139

139140

140-
def _parse_server_exception(response, url):
141+
def _parse_server_exception(
142+
response: requests.Response,
143+
url: str,
144+
file_elements: Dict,
145+
) -> OpenMLServerError:
141146
# OpenML has a sophisticated error system
142147
# where information about failures is provided. try to parse this
143148
try:
@@ -152,10 +157,27 @@ def _parse_server_exception(response, url):
152157
message = server_error['oml:message']
153158
additional_information = server_error.get('oml:additional_information')
154159
if code in [372, 512, 500, 482, 542, 674]:
160+
if additional_information:
161+
full_message = '{} - {}'.format(message, additional_information)
162+
else:
163+
full_message = message
164+
155165
# 512 for runs, 372 for datasets, 500 for flows
156166
# 482 for tasks, 542 for evaluations, 674 for setups
157-
return OpenMLServerNoResult(code, message, additional_information)
158-
full_message = '{} - {}'.format(message, additional_information)
167+
return OpenMLServerNoResult(
168+
code=code,
169+
message=full_message,
170+
)
171+
# 163: failure to validate flow XML (https://www.openml.org/api_docs#!/flow/post_flow)
172+
if code in [163] and file_elements is not None and 'description' in file_elements:
173+
# file_elements['description'] is the XML file description of the flow
174+
full_message = '\n{}\n{} - {}'.format(
175+
file_elements['description'],
176+
message,
177+
additional_information,
178+
)
179+
else:
180+
full_message = '{} - {}'.format(message, additional_information)
159181
return OpenMLServerException(
160182
code=code,
161183
message=full_message,

openml/exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class OpenMLServerException(OpenMLServerError):
1818

1919
# Code needs to be optional to allow the exceptino to be picklable:
2020
# https://stackoverflow.com/questions/16244923/how-to-make-a-custom-exception-class-with-multiple-init-args-pickleable # noqa: E501
21-
def __init__(self, message: str, code: str = None, url: str = None):
21+
def __init__(self, message: str, code: int = None, url: str = None):
2222
self.message = message
2323
self.code = code
2424
self.url = url

0 commit comments

Comments
 (0)