@@ -148,9 +148,10 @@ def do_query():
148148 # (hopefully) eventually recover the job.
149149 # https://github.com/googleapis/python-bigquery/issues/2134
150150 get_job_retry = retry
151- if get_job_retry is not None :
151+ if retry is not None :
152152 get_job_retry = retry .with_predicate (
153153 lambda exc : isinstance (exc , core_exceptions .NotFound )
154+ # Reference the original retry to avoid recursion.
154155 or retry ._predicate (exc )
155156 )
156157
@@ -168,11 +169,26 @@ def do_query():
168169 else :
169170 return query_job
170171
171- # Allow folks to turn off job_retry with an explicit None.
172172 if job_retry is None :
173173 future = do_query ()
174174 else :
175- future = job_retry (do_query )()
175+ # Per https://github.com/googleapis/python-bigquery/issues/2134, sometimes
176+ # we get a 404 error. In this case, if we get this far, assume that the job
177+ # doesn't actually exist and try again. We can't add 404 to the default
178+ # job_retry because that happens for errors like "this table does not
179+ # exist", which probably won't resolve with a retry.
180+ def do_query_predicate (exc ) -> bool :
181+ if isinstance (exc , core_exceptions .RetryError ):
182+ exc = exc .cause
183+
184+ if isinstance (exc , core_exceptions .NotFound ):
185+ return True
186+
187+ # Reference the original job_retry to avoid recursion.
188+ return job_retry ._predicate (exc )
189+
190+ do_query_retry = job_retry .with_predicate (do_query_predicate )
191+ future = do_query_retry (do_query )()
176192
177193 # The future might be in a failed state now, but if it's
178194 # unrecoverable, we'll find out when we ask for it's result, at which
0 commit comments