Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NOREF-Better error handling & logging #365

Merged
merged 9 commits into from
Sep 16, 2024
Merged

Conversation

Apophenia
Copy link
Contributor

Todo:

  • Check exception in query building function is handled correctly if query can't be formed
  • Ensure graceful failure if OCLC json does not contain error type

@@ -96,17 +96,20 @@ def _get_other_editions(self, oclc_number: int, offset: int=0):
)

if other_editions_response.status_code != 200:
logger.warning(f'OCLC other editions request failed with status {other_editions_response.status_code}')
logger.warning(
f"Other editions query for no {oclc_number} failed "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's use single quotation marks

logger.warning(
f"Other editions query for no {oclc_number} failed "
f"With status {other_editions_response.status_code} "
f"and reason {other_editions_response.json()['type']}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be careful with getting the json body. If it's a 500 error, there may not be a json body and we may error out here.

except Exception as e:
logger.error(f'Failed to query other editions endpoint {other_editions_url}', e)
except Exception as e:
logger.error(f'Failed to query other editions endpoint {other_editions_url}: Exception: {e}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not get the entire stack trace here, which may be helpful to debug.

@@ -133,7 +136,7 @@ def query_bibs(self, query: str):

return bibs
except Exception as e:
logger.error(f'Failed to query search bibs with query {query}', e)
logger.error(f'Failed to query search bibs with query {query}. Exception: {e}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

search_query = self.oclc_catalog_manager.generate_search_query(identifier, identifier_type, title, author)

try:
search_query = self.oclc_catalog_manager.generate_search_query(identifier, identifier_type, title, author)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm are we erring out when we generate the search query?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In main, if "generate search query" returns None because a search query can't be built, the code still sends the (empty) search query to OCLC and then fails with a warning level log and continues. I'm open to how exceptions should be handled but I do think we should avoid sending empty queries to OCLC - very flexible about how or where we do that!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to try a different rework

@@ -19,17 +24,17 @@ def addDCDWToUpdateList(self, rec):
existing = self.session.query(Record)\
.filter(Record.source_id == rec.record.source_id).first()
if existing:
print('EXISTING', existing)
logger.debug('Existing record: ' + str(existing))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! this is much needed haha

f'OCLC search bibs request for OCLC no {oclc_number} failed '
f'with status {other_editions_response.status_code}')
try:
oclc_error_type = other_editions_response.json()["type"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do get('type') here instead to just guard.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think json() could still throw a JSONDecodeError before the get() is run on type, but it could be split out such that the exception is narrowed to not include both the JSONDecodeError and the KeyError here - do you think that would be better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(The possibilities including: the response not having valid JSON, and the response having valid JSON but it might not contain a type)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we aren't handling the TypeError right? I think using get would prevent the KeyError.

@Apophenia Apophenia marked this pull request as ready for review September 13, 2024 21:45
Copy link
Contributor

@kylevillegas93 kylevillegas93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving for now - let's definitely cleanup the error handling and make sure we've documented/covered all of the edge cases.

@Apophenia Apophenia merged commit e6cb3fa into main Sep 16, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants