Merge: Not null types
[nit.git] / lib / github / github_curl.nit
index 6e2067b..8e70600 100644 (file)
@@ -24,7 +24,7 @@ class GithubCurl
        super Curl
 
        # Headers to use on all requests
-       var header: HeaderMap
+       var header: HeaderMap is noinit
 
        # OAuth token
        var auth: String
@@ -33,12 +33,7 @@ class GithubCurl
        # Eg. "Awesome-Octocat-App"
        var user_agent: String
 
-       init(auth: String, user_agent: String)
-       do
-               super
-               self.auth = auth
-               self.user_agent = user_agent
-
+       init do
                header = new HeaderMap
                header["Authorization"] = "token {auth}"
        end
@@ -71,13 +66,77 @@ class GithubCurl
                        abort
                else abort
        end
+
+       # Get the requested URI, and check the HTTP response.
+       # Then convert to JSON and check for Github errors.
+       # Unlike `get_and_check`, error do not trigger an abort but
+       # are reported as `GithubError`.
+       fun get_and_parse(uri: String): nullable Jsonable
+       do
+               var request = new CurlHTTPRequest(uri, self)
+               request.user_agent = user_agent
+               request.headers = header
+               var response = request.execute
+               if response isa CurlResponseSuccess then
+                       var obj = response.body_str.parse_json
+                       if obj isa JsonObject then
+                               if obj.keys.has("message") then
+                                       var title = "GithubAPIError"
+                                       var msg = obj["message"].to_s
+                                       var err = new GithubError(msg, title)
+                                       err.json["requested_uri"] = uri
+                                       err.json["status_code"] = response.status_code
+                                       return err
+                               end
+                       end
+                       return obj
+
+               else if response isa CurlResponseFailed then
+                       var title = "CurlResponseFailed"
+                       var msg = "Request to Github API failed"
+                       var err = new GithubError(msg, title)
+                       err.json["requested_uri"] = uri
+                       err.json["error_code"] = response.error_code
+                       err.json["response"] = response.error_msg
+                       return err
+               else abort
+       end
+
+end
+
+# An error thrown by the Github API.
+#
+# Depending on the kind of error, additionnal informations can be stored in
+# the error object.
+# Check the `json` value to find them.
+class GithubError
+       super Error
+       super Jsonable
+
+       # The name of the error.
+       var name: String
+
+       # The json content of the error.
+       var json = new JsonObject
+
+       redef init do
+               super
+               json["error"] = name.to_json
+               json["message"] = message.to_json
+       end
+
+       redef fun to_json do
+               return json.to_json
+       end
+
+       redef fun to_s do return "[{name}] {super}"
 end
 
 # Return the value of `git config --get github.oauthtoken`
 # return "" if no such a key
 fun get_github_oauth: String
 do
-       var p = new IProcess("git", "config", "--get", "github.oauthtoken")
+       var p = new ProcessReader("git", "config", "--get", "github.oauthtoken")
        var token = p.read_line
        p.wait
        p.close