Conditions | 11 |
Total Lines | 58 |
Code Lines | 36 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like oauth.GetDiscordAccessToken often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | package oauth |
||
29 | func GetDiscordAccessToken(ctx context.Context, code string) (string, error) { |
||
30 | reqBody := bytes.NewBufferString(fmt.Sprintf( |
||
31 | "client_id=%s&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s&scope=identify,email", |
||
32 | discordConfig.ClientID, |
||
33 | discordConfig.ClientSecret, |
||
34 | GetCallbackURL()+"/v2/security/discord_callback", |
||
35 | code, |
||
36 | )) |
||
37 | |||
38 | // POST request to set URL. |
||
39 | req, err := http.NewRequestWithContext(ctx, |
||
40 | http.MethodPost, |
||
41 | discordTokenURL, |
||
42 | reqBody, |
||
43 | ) |
||
44 | if err != nil { |
||
45 | slog.Error("Failed to get Discord access token", slog.Any("error", err)) |
||
46 | return "", errors.Wrap(err, RequestFailed) |
||
47 | } |
||
48 | |||
49 | if req == nil || req.Body == nil || req.Header == nil { |
||
50 | slog.Error("Failed to get Discord access token", slog.Any("error", err)) |
||
51 | return "", errors.New(RequestFailed) |
||
52 | } |
||
53 | |||
54 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
||
55 | req.Header.Set("Accept", "application/json") |
||
56 | |||
57 | // Get the response. |
||
58 | resp, resperr := http.DefaultClient.Do(req) |
||
59 | if resperr != nil { |
||
60 | slog.Error("Failed to get Discord access token", slog.Any("error", resperr)) |
||
61 | return "", errors.Wrap(resperr, ResponseFailed) |
||
62 | } |
||
63 | |||
64 | defer func(resp *http.Response) { |
||
65 | if resp != nil && resp.Body != nil { |
||
66 | resp.Body.Close() |
||
67 | } |
||
68 | }(resp) |
||
69 | |||
70 | // Response body converted to stringified JSON. |
||
71 | respbody, err := io.ReadAll(resp.Body) |
||
72 | if err != nil { |
||
73 | slog.Error("failed to read resp.body", slog.Any("error", err)) |
||
74 | return "", err |
||
75 | } |
||
76 | |||
77 | // Convert stringified JSON to a struct object of type githubAccessTokenResponse. |
||
78 | var ghresp discordAccessTokenResponse |
||
79 | err = GetJSONHelperInstance().GetJSONHelper().Unmarshal(respbody, &ghresp) |
||
80 | if err != nil { |
||
81 | return "", err |
||
82 | } |
||
83 | |||
84 | // Return the access token (as the rest of the |
||
85 | // details are relatively unnecessary for us). |
||
86 | return ghresp.AccessToken, nil |
||
87 | } |
||
121 |