// Exec executes the given request. Returns a GraphError if the response from Facebook is an error, or just // a normal error if something goes wrong before that or during unmarshaling. func (r *GraphRequest) Exec(target interface{}) error { p := r.Path if r.Version != Unversioned { p = "/" + string(r.Version) + "/" + p } p = path.Clean(p) url := url.URL{ Scheme: "https", Host: "graph.facebook.com", Path: p, RawQuery: url.Values(r.Query).Encode(), } req, _ := http.NewRequest(string(r.Method), url.String(), nil) if r.IsJSON { req.Header.Add("Accept", "application/json") } resp, err := r.client.Do(req) if err != nil { return fmt.Errorf("error setting up http request: %s", err) } buf, err := ioutil.ReadAll(resp.Body) if err != nil { return fmt.Errorf("error reading response body") } if resp.StatusCode != 200 { errorTarget := GraphError{} err = json.Unmarshal(buf, &errorTarget) if err != nil { return fmt.Errorf("couldn't unmarshal response into Graph Error: %s\n\t%s", err, string(buf)) } return errorTarget } if _, ok := target.(*[]byte); ok { *(target.(*[]byte)) = buf return nil } else if r.IsJSON { err = json.Unmarshal(buf, target) if err != nil { return fmt.Errorf("error unmarshaling response into %T: %s\n\n%s", target, err, string(buf)) } } else { return fmt.Errorf("invalid target type for non-json response: %T", target) } return nil }