diff --git a/bigquery/google/cloud/bigquery/job.py b/bigquery/google/cloud/bigquery/job.py index 6818dfba5a1f..589612bb0fb9 100644 --- a/bigquery/google/cloud/bigquery/job.py +++ b/bigquery/google/cloud/bigquery/job.py @@ -16,10 +16,12 @@ from __future__ import division +import concurrent.futures import copy import re import threading +import requests import six from six.moves import http_client @@ -3155,6 +3157,8 @@ def result( exc.message += self._format_for_exception(self.query, self.job_id) exc.query_job = self raise + except requests.exceptions.Timeout as exc: + six.raise_from(concurrent.futures.TimeoutError, exc) # If the query job is complete but there are no query results, this was # special job, such as a DDL query. Return an empty result set to diff --git a/bigquery/tests/unit/test_job.py b/bigquery/tests/unit/test_job.py index 9ca6fa858665..701a60533b46 100644 --- a/bigquery/tests/unit/test_job.py +++ b/bigquery/tests/unit/test_job.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import concurrent import copy import json import textwrap @@ -19,6 +20,7 @@ import mock import pytest +import requests from six.moves import http_client try: @@ -4604,6 +4606,26 @@ def test_result_error(self): expected_line = "{}:{}".format(i, line) assert expected_line in full_text + def test_result_transport_timeout_error(self): + query = textwrap.dedent( + """ + SELECT foo, bar + FROM table_baz + WHERE foo == bar""" + ) + + client = _make_client(project=self.PROJECT) + job = self._make_one(self.JOB_ID, query, client) + call_api_patch = mock.patch( + "google.cloud.bigquery.client.Client._call_api", + autospec=True, + side_effect=requests.exceptions.Timeout("Server response took too long."), + ) + + # Make sure that timeout errors get rebranded to concurrent futures timeout. + with call_api_patch, self.assertRaises(concurrent.futures.TimeoutError): + job.result(timeout=1) + def test__begin_error(self): from google.cloud import exceptions