1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Fix JSON parsing

Issue #600 points out Jenkins module panics occasionally
I noticed that a number of places panic because of JSON parsing
Centralize JSON parsing, have it return an error, and have widgets
report the error
This commit is contained in:
Sean Smith 2019-09-07 15:10:37 -04:00
parent 32884e5de4
commit 36fbad54d8
8 changed files with 73 additions and 162 deletions

View File

@ -1,13 +1,11 @@
package circleci
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"github.com/wtfutil/wtf/utils"
)
type Client struct {
@ -30,7 +28,10 @@ func (client *Client) BuildsFor() ([]*Build, error) {
return builds, err
}
parseJson(&builds, resp.Body)
err = utils.ParseJson(&builds, resp.Body)
if err != nil {
return builds, err
}
return builds, nil
}
@ -66,20 +67,3 @@ func (client *Client) circleRequest(path string) (*http.Response, error) {
return resp, nil
}
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,13 +1,11 @@
package gitter
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
"github.com/wtfutil/wtf/utils"
)
func GetMessages(roomId string, numberOfMessages int, apiToken string) ([]Message, error) {
@ -18,7 +16,10 @@ func GetMessages(roomId string, numberOfMessages int, apiToken string) ([]Messag
return nil, err
}
parseJson(&messages, resp.Body)
err = utils.ParseJson(&messages, resp.Body)
if err != nil {
return nil, err
}
return messages, nil
}
@ -31,7 +32,10 @@ func GetRoom(roomUri, apiToken string) (*Room, error) {
return nil, err
}
parseJson(&rooms, resp.Body)
err = utils.ParseJson(&rooms, resp.Body)
if err != nil {
return nil, err
}
for _, room := range rooms.Results {
if room.URI == roomUri {
@ -65,20 +69,3 @@ func apiRequest(path, apiToken string) (*http.Response, error) {
return resp, nil
}
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,14 +1,12 @@
package hackernews
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
"strings"
"github.com/wtfutil/wtf/utils"
)
func GetStories(storyType string) ([]int, error) {
@ -21,7 +19,10 @@ func GetStories(storyType string) ([]int, error) {
return storyIds, err
}
parseJson(&storyIds, resp.Body)
err = utils.ParseJson(&storyIds, resp.Body)
if err != nil {
return storyIds, err
}
}
return storyIds, nil
@ -35,7 +36,10 @@ func GetStory(id int) (Story, error) {
return story, err
}
parseJson(&story, resp.Body)
err = utils.ParseJson(&story, resp.Body)
if err != nil {
return story, err
}
return story, nil
}
@ -61,20 +65,3 @@ func apiRequest(path string) (*http.Response, error) {
return resp, nil
}
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,27 +1,26 @@
package jenkins
import (
"bytes"
"crypto/tls"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strings"
"github.com/wtfutil/wtf/utils"
)
func (widget *Widget) Create(jenkinsURL string, username string, apiKey string) (*View, error) {
const apiSuffix = "api/json?pretty=true"
view := &View{}
parsedSuffix, err := url.Parse(apiSuffix)
if err != nil {
return &View{}, err
return view, err
}
parsedJenkinsURL, err := url.Parse(ensureLastSlash(jenkinsURL))
if err != nil {
return &View{}, err
return view, err
}
jenkinsAPIURL := parsedJenkinsURL.ResolveReference(parsedSuffix)
@ -38,11 +37,13 @@ func (widget *Widget) Create(jenkinsURL string, username string, apiKey string)
resp, err := httpClient.Do(req)
if err != nil {
return &View{}, err
return view, err
}
view := &View{}
parseJson(view, resp.Body)
err = utils.ParseJson(view, resp.Body)
if err != nil {
return view, err
}
jobs := []Job{}
@ -61,22 +62,3 @@ func (widget *Widget) Create(jenkinsURL string, username string, apiKey string)
func ensureLastSlash(url string) string {
return strings.TrimRight(url, "/") + "/"
}
/* -------------------- Unexported Functions -------------------- */
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,15 +1,13 @@
package jira
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/wtfutil/wtf/utils"
)
func (widget *Widget) IssuesFor(username string, projects []string, jql string) (*SearchResult, error) {
@ -40,7 +38,10 @@ func (widget *Widget) IssuesFor(username string, projects []string, jql string)
}
searchResult := &SearchResult{}
parseJson(searchResult, resp.Body)
err = utils.ParseJson(searchResult, resp.Body)
if err != nil {
return nil, err
}
return searchResult, nil
}
@ -79,23 +80,6 @@ func (widget *Widget) jiraRequest(path string) (*http.Response, error) {
return resp, nil
}
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}
func getProjectQuery(projects []string) string {
singleEmptyProject := len(projects) == 1 && len(projects[0]) == 0
if len(projects) == 0 || singleEmptyProject {

View File

@ -1,13 +1,11 @@
package rollbar
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"github.com/wtfutil/wtf/utils"
)
func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*ActiveItems, error) {
@ -20,7 +18,7 @@ func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*A
return items, err
}
parseJSON(&items, resp.Body)
err = utils.ParseJson(&items, resp.Body)
return items, nil
}
@ -56,20 +54,3 @@ func rollbarItemRequest(accessToken, assignedToName string, activeOnly bool) (*h
return resp, nil
}
func parseJSON(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,13 +1,11 @@
package travisci
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"github.com/wtfutil/wtf/utils"
)
var TRAVIS_HOSTS = map[bool]string{
@ -25,7 +23,10 @@ func BuildsFor(settings *Settings) (*Builds, error) {
return builds, err
}
parseJson(&builds, resp.Body)
err = utils.ParseJson(&builds, resp.Body)
if err != nil {
return builds, err
}
return builds, nil
}
@ -67,20 +68,3 @@ func travisBuildRequest(settings *Settings) (*http.Response, error) {
return resp, nil
}
func parseJson(obj interface{}, text io.Reader) {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
panic(err)
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
panic(err)
}
}
}

View File

@ -1,7 +1,10 @@
package utils
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os/exec"
"regexp"
@ -121,3 +124,22 @@ func ReadFileBytes(filePath string) ([]byte, error) {
return fileData, nil
}
// ParseJson is a standard JSON reader from text
func ParseJson(obj interface{}, text io.Reader) error {
jsonStream, err := ioutil.ReadAll(text)
if err != nil {
return err
}
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
for {
if err := decoder.Decode(obj); err == io.EOF {
break
} else if err != nil {
return err
}
}
return nil
}