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 all 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
4 changes: 1 addition & 3 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# These are supported funding model platforms

ko_fi: #hedyli
custom: https://issuehunt.io/r/hedythedev/starcli?tab=idle
issuehunt: hedythedev/starcli
49 changes: 38 additions & 11 deletions starcli/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
""" 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_actions,
)


@click.command()
Expand Down Expand Up @@ -98,16 +105,36 @@ 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 == "retry":
for i in range(15, 0, -1):
print(
f"{status_actions[handling_code]} {i} seconds...", end="\r"
) # Print and update a timer
sleep(1)
elif handling_code in status_actions:
print(status_actions[handling_code])
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
71 changes: 60 additions & 11 deletions starcli/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@

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

status_actions = {
"retry": "Failed to retrieve data. Retrying in ",
"invalid": "The server was unable to process the request.",
"not_found": "The server indicated no data was found.",
"unsupported": "The request is not supported.",
"unknown": "An unknown error occurred.",
"valid": "The request returned successfully, but an unknown exception occurred.",
}


def debug_requests_on():
""" Turn on the logging for requests """
Expand Down Expand Up @@ -124,13 +133,11 @@ 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
if request is None:
return request

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


def search_github_trending(
Expand All @@ -144,11 +151,12 @@ 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)
if request is None:
return request

page = request.text

soup = BeautifulSoup(page, "lxml")
repo_list = soup.find_all("article", class_="Box-row")
Expand Down Expand Up @@ -209,3 +217,44 @@ 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

http_code_handling = {
"200": "valid",
"202": "valid",
"204": "valid",
"400": "invalid",
"401": "retry",
"403": "retry",
"404": "not_found",
"405": "invalid",
"422": "not_found",
"500": "invalid",
"501": "invalid",
}

try:
return http_code_handling[str(int_status_code)]
except KeyError as ke:
return "unsupported"