Skip to content

Commit

Permalink
Merge pull request #71 from atlanhq/FT-840
Browse files Browse the repository at this point in the history
FT-840: Improve unhandled exception message logging
  • Loading branch information
0xquark authored Dec 28, 2024
2 parents daf36f6 + 88a96c9 commit c4b5c01
Showing 1 changed file with 59 additions and 20 deletions.
79 changes: 59 additions & 20 deletions atlan/assets/errors.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package assets

import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)

type ErrorInfo struct {
Expand All @@ -15,8 +18,8 @@ type ErrorInfo struct {
type AtlanError struct {
ErrorCode ErrorInfo
Args []interface{}
OriginalError string // Error received from Atlan API

OriginalError string // Error received from Atlan API
Causes []Cause // List of causes from API response
}

func (e AtlanError) Error() string {
Expand All @@ -27,6 +30,13 @@ func (e AtlanError) Error() string {
if e.OriginalError != "" {
errorMessage += "\nError response from server: " + e.OriginalError
}

if len(e.Causes) > 0 {
errorMessage += "\nCauses:\n"
for _, cause := range e.Causes {
errorMessage += fmt.Sprintf("- %s: %s (Location: %s)\n", cause.ErrorType, cause.ErrorMessage, cause.Location)
}
}
return errorMessage
}

Expand Down Expand Up @@ -152,8 +162,8 @@ var errorCodes = map[ErrorCode]ErrorInfo{
INVALID_REQUEST_PASSTHROUGH: {
HTTPErrorCode: 400,
ErrorID: "ATLAN-GO-400-000",
ErrorMessage: "Server responded with %s: %s. Check the details of the server's message to correct your request.",
UserAction: "",
ErrorMessage: "Server responded with %s: %s.%s",
UserAction: "Check the details of the server's message to correct your request.",
},
MISSING_GROUP_ID: {
HTTPErrorCode: 400,
Expand Down Expand Up @@ -482,7 +492,7 @@ var errorCodes = map[ErrorCode]ErrorInfo{
PERMISSION_PASSTHROUGH: {
HTTPErrorCode: 403,
ErrorID: "ATLAN-GO-403-000",
ErrorMessage: "Server responded with %s: %s",
ErrorMessage: "Server responded with %s: %s.%s",
UserAction: "Check the details of the server's message to correct your request.",
},
UNABLE_TO_IMPERSONATE: {
Expand All @@ -500,7 +510,7 @@ var errorCodes = map[ErrorCode]ErrorInfo{
NOT_FOUND_PASSTHROUGH: {
HTTPErrorCode: 404,
ErrorID: "ATLAN-GO-404-000",
ErrorMessage: "Server responded with %s: %s",
ErrorMessage: "Server responded with %s: %s.",
UserAction: "Check the details of the server's message to correct your request.",
},
ASSET_NOT_FOUND_BY_GUID: {
Expand Down Expand Up @@ -668,7 +678,7 @@ var errorCodes = map[ErrorCode]ErrorInfo{
CONFLICT_PASSTHROUGH: {
HTTPErrorCode: 409,
ErrorID: "ATLAN-GO-409-000",
ErrorMessage: "Server responded with %s: %s",
ErrorMessage: "Server responded with %s: %s.%s",
UserAction: "Check the details of the server's message to correct your request.",
},
RESERVED_SERVICE_TYPE: {
Expand All @@ -680,13 +690,13 @@ var errorCodes = map[ErrorCode]ErrorInfo{
RATE_LIMIT_PASSTHROUGH: {
HTTPErrorCode: 429,
ErrorID: "ATLAN-GO-429-000",
ErrorMessage: "Server responded with %s: %s",
ErrorMessage: "Server responded with %s: %s.%s",
UserAction: "Check the details of the server's message to correct your request.",
},
ERROR_PASSTHROUGH: {
HTTPErrorCode: 500,
ErrorID: "ATLAN-GO-500-000",
ErrorMessage: "Server responded with %s: %s",
ErrorMessage: "Server responded with %s: %s.%s",
UserAction: "Check the details of the server's message to correct your request.",
},
DUPLICATE_CUSTOM_ATTRIBUTES: {
Expand Down Expand Up @@ -727,27 +737,53 @@ var errorCodes = map[ErrorCode]ErrorInfo{
},
}

type Cause struct {
ErrorType string `json:"errorType"`
ErrorMessage string `json:"errorMessage"`
Location string `json:"location"`
}

type ErrorResponse struct {
Causes []Cause `json:"causes"`
ErrorID string `json:"errorId"`
Message string `json:"message"`
}

func handleApiError(response *http.Response, originalError error) error {
if response == nil {
return ThrowAtlanError(originalError, CONNECTION_ERROR, nil)
}
rc := response.StatusCode
body, _ := io.ReadAll(response.Body)
var errorResponse ErrorResponse
var causes []Cause

if err := json.Unmarshal(body, &errorResponse); err == nil {
fmt.Println(errorResponse)
causes = errorResponse.Causes
}
var causesString string
if len(causes) > 0 {
for _, cause := range causes {
causesString += fmt.Sprintf(" %s : %s : %s \n", cause.ErrorType, cause.ErrorMessage, cause.Location)
}
}

switch rc {
case 400:
return ThrowAtlanError(originalError, INVALID_REQUEST_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, INVALID_REQUEST_PASSTHROUGH, nil, causesString)
case 404:
return ThrowAtlanError(originalError, NOT_FOUND_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, NOT_FOUND_PASSTHROUGH, nil, causesString)
case 401:
return ThrowAtlanError(originalError, AUTHENTICATION_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, AUTHENTICATION_PASSTHROUGH, nil, causesString)
case 403:
return ThrowAtlanError(originalError, PERMISSION_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, PERMISSION_PASSTHROUGH, nil, causesString)
case 409:
return ThrowAtlanError(originalError, CONFLICT_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, CONFLICT_PASSTHROUGH, nil, causesString)
case 429:
return ThrowAtlanError(originalError, RATE_LIMIT_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, RATE_LIMIT_PASSTHROUGH, nil, causesString)
default:
return ThrowAtlanError(originalError, ERROR_PASSTHROUGH, nil)
return ThrowAtlanError(originalError, ERROR_PASSTHROUGH, nil, causesString)
}
}

Expand All @@ -768,10 +804,13 @@ func ThrowAtlanError(err error, sdkError ErrorCode, suggestion *string, args ...
atlanError.ErrorCode.UserAction = *suggestion
}

if len(args) != 0 {
atlanError.ErrorCode.ErrorMessage = fmt.Sprintf(
atlanError.ErrorCode.ErrorMessage, atlanError.Args...,
)
if len(args) > 0 {
if strings.Contains(atlanError.ErrorCode.ErrorMessage, "%") {
atlanError.ErrorCode.ErrorMessage = fmt.Sprintf(
atlanError.ErrorCode.ErrorMessage, args...,
)
}
atlanError.Args = args
}

return &atlanError
Expand Down

0 comments on commit c4b5c01

Please sign in to comment.