Repository: python-discord/bot

Issue:
Ping Command Bugs
There are a couple bugs in the ping command, that only manifest in local development.

## Bug 1: `gaierror: [Errno 11001] getaddrinfo failed`
This bug is pretty easy to explain. On many development bots, the site URL will have some sort of port (for example `pythondiscord.local:8000` or `web:8000`).  aioping.ping does not seem to handle that, and will throw a getadderinfo error. ([Full TB if needed](https://paste.pythondiscord.com/pahuherice.sql)). This issue does not affect the Python bot, as the URL does not contain a port.

The fix for this should be simple enough, you just need to extract netloc from the URL, and pass it to the ping function. One possible way to do that could be through using the builtin [urllib.parse.urlparse](https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse).

## Bug 2: Negative Processing Time
Last I checked, my bot had not yet developed time-traveling abilities, which makes this output a bit strange:

![Time Magic](https://user-images.githubusercontent.com/47495861/107149169-36182780-6968-11eb-94a1-5465728c4dfa.png)

The line that calculates that time is:
https://github.com/python-discord/bot/blob/888c427466b370b9ae51e47496e979c2b6faed0c/bot/exts/utils/ping.py#L36

I'm not too sure why this happens, but it happens consistently. My guess would be a difference between the internal timing for discord, and the internal timing of my system. This is also not a problem on the production server.

I propose that all negative times be replaced with a warning, or a 0, or something to signify a nonsensical result. If someone has a better explanation or a better fix, feel free to comment.


Discussion:
I can reproduce the first bug, and the second one by changing my OS time. 

Since the second bug is because of a host configuration issue, I'd rather show it as a warning, such as `Failed to get valid current time` instead of using zero. 
The first bug affects my instance as well.

I agree with Akarys that displaying a warning would be optimal in the second scenario. Adding a "if time is less than 0, use this," to the ping command might be sufficient. Something like `Invalid time configuration` or `Could not fetch` might be clear enough.
Assigned myself to this.

Resolving patch:
diff --git a/bot/exts/utils/ping.py b/bot/exts/utils/ping.py
--- a/bot/exts/utils/ping.py
+++ b/bot/exts/utils/ping.py
@@ -1,4 +1,5 @@
 import socket
+import urllib.parse
 from datetime import datetime
 
 import aioping
@@ -34,11 +35,19 @@ async def ping(self, ctx: commands.Context) -> None:
         # datetime.datetime objects do not have the "milliseconds" attribute.
         # It must be converted to seconds before converting to milliseconds.
         bot_ping = (datetime.utcnow() - ctx.message.created_at).total_seconds() * 1000
-        bot_ping = f"{bot_ping:.{ROUND_LATENCY}f} ms"
+        if bot_ping <= 0:
+            bot_ping = "Your clock is out of sync, could not calculate ping."
+        else:
+            bot_ping = f"{bot_ping:.{ROUND_LATENCY}f} ms"
 
         try:
-            delay = await aioping.ping(URLs.site, family=socket.AddressFamily.AF_INET) * 1000
-            site_ping = f"{delay:.{ROUND_LATENCY}f} ms"
+            url = urllib.parse.urlparse(URLs.site_schema + URLs.site).hostname
+            try:
+                delay = await aioping.ping(url, family=socket.AddressFamily.AF_INET) * 1000
+                site_ping = f"{delay:.{ROUND_LATENCY}f} ms"
+            except OSError:
+                # Some machines do not have permission to run ping
+                site_ping = "Permission denied, could not ping."
 
         except TimeoutError:
             site_ping = f"{Emojis.cross_mark} Connection timed out."


Test patch: