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

Error Handling for HTTP Status Codes #67

Merged
merged 10 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 53 additions & 11 deletions starcli/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
""" starcli.__main__ """

import click
from time import sleep

from .layouts import list_layout, table_layout, grid_layout, shorten_count
from .search import search, debug_requests_on, search_github_trending
from .search import (
search,
debug_requests_on,
search_github_trending,
search_error,
STATUS_RETRY,
STATUS_EXIT,
STATUS_NOT_FOUND,
STATUS_VALID,
STATUS_UNSUPPORTED,
)


@click.command()
Expand Down Expand Up @@ -98,16 +109,47 @@ def cli(
import logging

debug_requests_on()
if (
not spoken_language and not date_range
): # if filtering by spoken language and date range not required
tmp_repos = search(
lang, created, last_updated, stars, topics, user, debug, order
)
else:
tmp_repos = search_github_trending(
lang, spoken_language, order, stars, date_range
)

while True:
try:
if (
not spoken_language and not date_range
): # if filtering by spoken language and date range not required
tmp_repos = search(
lang, created, last_updated, stars, topics, user, debug, order
)
else:
tmp_repos = search_github_trending(
lang, spoken_language, order, stars, date_range
)
break # Need this here to break out of the loop if the request is successful
except AssertionError as ae: # If a request is unsuccessful, expect an assertion error
status_code = str(ae).split(" ")[3]
handling_code = search_error(status_code)
if handling_code == STATUS_RETRY:
for i in range(15, 0, -1):
print(
f"Failed to retrieve data. Retrying in {i} seconds...", end="\r"
) # Print and update a timer
sleep(1)
elif handling_code == STATUS_EXIT:
print("The server was unable to process the request.")
return
elif handling_code == STATUS_NOT_FOUND:
print("The server indicated no data was found.")
return
elif handling_code == STATUS_UNSUPPORTED:
print("An unknown error occurred.")
return
elif handling_code == STATUS_VALID:
print(
"The request returned successfully, but an unknown exception occurred."
)
return
else:
print("An invalid handling code was returned.")
return

if not tmp_repos: # if search() returned None
return
repos = tmp_repos[0:limit_results]
Expand Down
56 changes: 45 additions & 11 deletions starcli/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

date_range_map = {"today": "daily", "this-week": "weekly", "this-month": "monthly"}

STATUS_RETRY = "retry"
STATUS_EXIT = "exit"
STATUS_NOT_FOUND = "not found"
STATUS_VALID = "valid"
STATUS_UNSUPPORTED = "unsupported"


def debug_requests_on():
""" Turn on the logging for requests """
Expand Down Expand Up @@ -124,13 +130,9 @@ def search(
if debug:
print("DEBUG: search: url:", url) # print the url when debugging

try:
repositories = requests.get(url).json() # get the response using the url
except requests.exceptions.ConnectionError:
secho("Internet connection error...", fg="bright_red")
return None
request = get_valid_request(url)
hedyhli marked this conversation as resolved.
Show resolved Hide resolved

return repositories["items"]
return request.json()["items"]


def search_github_trending(
Expand All @@ -144,11 +146,9 @@ def search_github_trending(
url += f"&spoken_language_code={spoken_language}" # filter by spoken language
if date_range:
url += f"&since={date_range_map[date_range]}"
try:
page = requests.get(url).text
except requests.exceptions.ConnectionError:
secho("Internet connection error...", fg="bright_red")
return None

request = get_valid_request(url)
page = request.text

soup = BeautifulSoup(page, "lxml")
repo_list = soup.find_all("article", class_="Box-row")
Expand Down Expand Up @@ -209,3 +209,37 @@ def search_github_trending(
if order == "asc":
return sorted(repositories, key=lambda repo: repo["stargazers_count"])
return sorted(repositories, key=lambda repo: repo["stargazers_count"], reverse=True)


def get_valid_request(url):
"""
Provide a URL to submit a GET request for and handle a connection error or raise an assertion error if an HTTP status code indicating anything other than a success was received.
"""
try:
request = requests.get(url)
except requests.exceptions.ConnectionError:
secho("Internet connection error...", fg="bright_red")
return None
assert request.status_code in (200, 202), f"HTTP Status Code: {request.status_code}"
return request


def search_error(status_code):
"""
This returns a directive on how to handle a given HTTP status code.
"""
int_status_code = int(
status_code
) # Need to make sure the status code is an integer
if int_status_code == 403:
return STATUS_RETRY
elif int_status_code == 404:
return STATUS_NOT_FOUND
elif int_status_code == 422:
return STATUS_NOT_FOUND
elif int_status_code >= 200 and int_status_code < 300: # This should not be used
return STATUS_VALID
elif int_status_code >= 500 and int_status_code < 600:
return STATUS_EXIT
else:
return STATUS_UNSUPPORTED