added error message
This commit is contained in:
+67
-11
@@ -162,7 +162,32 @@ func GoogleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
userInfo, err := FetchGoogleUserInfo(w, r)
|
||||
if err != nil {
|
||||
helper.RespondWithError(w, http.StatusBadGateway, "Failed to fetch user information from Google")
|
||||
errMsg := err.Error()
|
||||
helper.LogError(err, "Failed to fetch Google user info")
|
||||
|
||||
// Provide user-friendly error messages for different scenarios
|
||||
if strings.Contains(errMsg, "TLS handshake timeout") {
|
||||
helper.RespondWithError(w, http.StatusGatewayTimeout, "Connection to Google failed due to network issues. Please try again in a moment.")
|
||||
return
|
||||
}
|
||||
if strings.Contains(errMsg, "timeout") {
|
||||
helper.RespondWithError(w, http.StatusGatewayTimeout, "Request to Google took too long. Please try again.")
|
||||
return
|
||||
}
|
||||
if strings.Contains(errMsg, "connection refused") || strings.Contains(errMsg, "no such host") {
|
||||
helper.RespondWithError(w, http.StatusServiceUnavailable, "Unable to reach Google authentication servers. Please check your internet connection and try again.")
|
||||
return
|
||||
}
|
||||
if strings.Contains(errMsg, "status 401") {
|
||||
helper.RespondWithError(w, http.StatusUnauthorized, "Invalid authorization code. Please start the login process again.")
|
||||
return
|
||||
}
|
||||
if strings.Contains(errMsg, "status 403") {
|
||||
helper.RespondWithError(w, http.StatusForbidden, "Access to Google authentication was denied. Please try again later.")
|
||||
return
|
||||
}
|
||||
|
||||
helper.RespondWithError(w, http.StatusBadGateway, "Failed to fetch user information from Google. Please try again.")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -295,25 +320,48 @@ func FetchGoogleUserInfo(w http.ResponseWriter, r *http.Request) (models.UserGoo
|
||||
log.Print("Authorization code received: ", code)
|
||||
token, err := googleOauthConfig.Exchange(context.Background(), code)
|
||||
if err != nil {
|
||||
helper.LogError(err, "Error exchanging token")
|
||||
// http.Redirect(w, r, DashboardBaseURL, http.StatusSeeOther)
|
||||
return models.UserGoogleInfo{}, err
|
||||
helper.LogError(err, "Error exchanging authorization code for token")
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("failed to exchange authorization code: %w", err)
|
||||
}
|
||||
|
||||
helper.LogInfo(fmt.Sprintf("Access Token: %s", token.AccessToken))
|
||||
|
||||
client := googleOauthConfig.Client(context.Background(), token)
|
||||
// Create a context with a 30-second timeout for the userinfo request
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
client := googleOauthConfig.Client(ctx, token)
|
||||
req, err := http.NewRequest("GET", "https://www.googleapis.com/oauth2/v1/userinfo?alt=json", nil)
|
||||
if err != nil {
|
||||
helper.LogError(err, "Error creating request")
|
||||
return models.UserGoogleInfo{}, err
|
||||
helper.LogError(err, "Error creating request to fetch user info")
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("failed to create userinfo request: %w", err)
|
||||
}
|
||||
req.Header.Set("Authorization", bearerPrefix+token.AccessToken)
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
helper.LogError(err, "Error sending request")
|
||||
return models.UserGoogleInfo{}, err
|
||||
errMsg := fmt.Sprintf("Failed to fetch user info from Google: %v", err)
|
||||
helper.LogError(err, errMsg)
|
||||
|
||||
// Provide more specific error messages for common issues
|
||||
if os.IsTimeout(err) {
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("request timed out: Google userinfo endpoint took too long to respond (timeout: 30s)")
|
||||
}
|
||||
if strings.Contains(err.Error(), "net/http: TLS handshake timeout") {
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("TLS handshake timeout: Unable to establish secure connection to Google")
|
||||
}
|
||||
if strings.Contains(err.Error(), "context deadline exceeded") {
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("request deadline exceeded: Connection attempt exceeded 30 second timeout")
|
||||
}
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("connection refused: Cannot reach Google servers")
|
||||
}
|
||||
if strings.Contains(err.Error(), "no such host") {
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("DNS resolution failed: Cannot resolve googleapis.com")
|
||||
}
|
||||
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("network error while fetching user info: %w", err)
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
@@ -322,10 +370,18 @@ func FetchGoogleUserInfo(w http.ResponseWriter, r *http.Request) (models.UserGoo
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
// Check HTTP status code
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
bodyBytes, _ := io.ReadAll(resp.Body)
|
||||
errMsg := fmt.Sprintf("Google API returned status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||
helper.LogError(nil, errMsg)
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("google api error (status %d): %s", resp.StatusCode, string(bodyBytes))
|
||||
}
|
||||
|
||||
var userInfo models.UserGoogleInfo
|
||||
if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil {
|
||||
helper.LogError(err, "Error decoding user info")
|
||||
return models.UserGoogleInfo{}, err
|
||||
helper.LogError(err, "Error decoding user info from Google response")
|
||||
return models.UserGoogleInfo{}, fmt.Errorf("failed to parse user info response: %w", err)
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user