Skip to content

Commit

Permalink
fix(cli): consolidate and update backend error handling (#55)
Browse files Browse the repository at this point in the history
* fix(cli): consolidate and repair backend error handling

The same error handling code is copy-pasted all over the backend.  Consolidate this code in 1 common error handler function so it's easier to update next time.
Then, fixed the code that's not handling non-cfm-service errors correctly.
Also, need to fix potential memory leaks that comes from NOT using "defer response.Body.Close()" after a call into cfm-service.

* fix(cli): Remove unnecessary log message.

* docs(cli): add function description

* fix(cli): fix wrong variable name
  • Loading branch information
scott-howe-1 authored Nov 22, 2024
1 parent 076d4b7 commit bf8b702
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 599 deletions.
1 change: 0 additions & 1 deletion cli/pkg/serviceLib/serviceRequests/blades.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ func (r *ServiceRequestListBlades) Execute() (*serviceWrap.ApplianceBladeSummary

klog.V(4).InfoS(fmt.Sprintf("%T", *r), "ServiceTcp", fmt.Sprintf("%+v", *r.ServiceTcp))
klog.V(4).InfoS(fmt.Sprintf("%T", *r), "ApplianceId", fmt.Sprintf("%+v", *r.ApplianceId))
klog.V(4).InfoS(fmt.Sprintf("%T", *r), "BladeId", fmt.Sprintf("%+v", *r.BladeId))

serviceClient := serviceWrap.GetServiceClient(r.ServiceTcp.GetIp(), r.ServiceTcp.GetPort())

Expand Down
111 changes: 34 additions & 77 deletions cli/pkg/serviceLib/serviceWrap/appliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package serviceWrap

import (
"context"
"encoding/json"
"fmt"

service "cfm/pkg/client"
Expand All @@ -16,19 +15,12 @@ func AddAppliance(client *service.APIClient, creds *service.Credentials) (*servi
request := client.DefaultAPI.AppliancesPost(context.Background())
request = request.Credentials(*creds)
appliance, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: AddAppliance", "applianceId", appliance.GetId())
Expand All @@ -39,19 +31,12 @@ func AddAppliance(client *service.APIClient, creds *service.Credentials) (*servi
func DeleteApplianceById(client *service.APIClient, applId string) (*service.Appliance, error) {
request := client.DefaultAPI.AppliancesDeleteById(context.Background(), applId)
appliance, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: DeleteApplianceById", "applianceId", appliance.GetId())
Expand All @@ -63,42 +48,28 @@ func GetAllAppliances(client *service.APIClient) (*[]*service.Appliance, error)
var appliances []*service.Appliance

//Get existing appliances
requestGetAppls := client.DefaultAPI.AppliancesGet(context.Background())
collection, response, err := requestGetAppls.Execute()
request := client.DefaultAPI.AppliancesGet(context.Background())
collection, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", requestGetAppls, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
requestGetAppls, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(4).InfoS("success: AppliancesGet", "count", collection.GetMemberCount())

for _, member := range collection.GetMembers() {
id := ReadLastItemFromUri(member.GetUri())
requestGetApplById := client.DefaultAPI.AppliancesGetById(context.Background(), id)
appliance, response, err := requestGetApplById.Execute()
request2 := client.DefaultAPI.AppliancesGetById(context.Background(), id)
appliance, response2, err := request2.Execute()
if response2 != nil {
defer response2.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", requestGetApplById, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
requestGetApplById, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response2, err)
return nil, fmt.Errorf("execute failure(%T): %w", request2, newErr)
}

klog.V(4).InfoS("success: AppliancesGetById", "applianceId", appliance.GetId())
Expand All @@ -115,19 +86,12 @@ func RenameApplianceById(client *service.APIClient, applianceId string, newAppli
request := client.DefaultAPI.AppliancesUpdateById(context.Background(), applianceId)
request = request.NewApplianceId(newApplianceId)
appliance, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: RenameApplianceById", "request", request)
Expand All @@ -138,19 +102,12 @@ func RenameApplianceById(client *service.APIClient, applianceId string, newAppli
func ResyncApplianceById(client *service.APIClient, applianceId string) (*service.Appliance, error) {
request := client.DefaultAPI.AppliancesResyncById(context.Background(), applianceId)
appliance, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: ResyncApplianceById", "applianceId", appliance.GetId())
Expand Down
137 changes: 40 additions & 97 deletions cli/pkg/serviceLib/serviceWrap/blade.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package serviceWrap

import (
"context"
"encoding/json"
"fmt"

service "cfm/pkg/client"
Expand Down Expand Up @@ -54,19 +53,12 @@ func AddBlade(client *service.APIClient, applianceId string, bladeCreds *service
request := client.DefaultAPI.BladesPost(context.Background(), applianceId)
request = request.Credentials(*bladeCreds)
blade, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: AddBlade", "bladeId", blade.GetId(), "applianceId", applianceId)
Expand All @@ -77,19 +69,12 @@ func AddBlade(client *service.APIClient, applianceId string, bladeCreds *service
func DeleteBladeById(client *service.APIClient, applId, bladeId string) (*service.Blade, error) {
request := client.DefaultAPI.BladesDeleteById(context.Background(), applId, bladeId)
blade, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: DeleteBladeById", "applianceId", applId, "bladeID", blade.GetId())
Expand All @@ -103,19 +88,12 @@ func FindBladeById_SingleAppl(client *service.APIClient, applId, bladeId string)
request := client.DefaultAPI.BladesGetById(context.Background(), applId, bladeId)
//TODO: What does this api do when the blade is empty
blade, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: FindBladeById_SingleAppl", "applianceId", applId, "bladeId", blade.GetId())
Expand All @@ -130,19 +108,12 @@ func FindBladeById_AllAppls(client *service.APIClient, bladeId string) (*Applian
//Get all existing appliances
request := client.DefaultAPI.AppliancesGet(context.Background())
applColl, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(4).InfoS("success: AppliancesGet", "applCount", applColl.GetMemberCount())
Expand Down Expand Up @@ -173,19 +144,12 @@ func GetAllBlades_SingleAppl(client *service.APIClient, applId string) (*[]*serv

request := client.DefaultAPI.BladesGet(context.Background(), applId)
bladeColl, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(4).InfoS("success: BladesGet", "applianceId", applId, "bladeCount", bladeColl.GetMemberCount())
Expand All @@ -211,19 +175,12 @@ func GetAllBlades_AllAppls(client *service.APIClient) (*ApplianceBladeSummary, e
//Get all existing appliances
request := client.DefaultAPI.AppliancesGet(context.Background())
applColl, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(4).InfoS("success: AppliancesGet", "applCount", applColl.GetMemberCount())
Expand All @@ -247,19 +204,12 @@ func RenameBladeById(client *service.APIClient, applId string, bladeId string, n
request := client.DefaultAPI.BladesUpdateById(context.Background(), applId, bladeId)
request = request.NewBladeId(newBladeId)
blade, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: RenameBladeById", "request", request)
Expand All @@ -270,19 +220,12 @@ func RenameBladeById(client *service.APIClient, applId string, bladeId string, n
func ResyncBladeById(client *service.APIClient, applId, bladeId string) (*service.Blade, error) {
request := client.DefaultAPI.BladesResyncById(context.Background(), applId, bladeId)
blade, response, err := request.Execute()
if response != nil {
defer response.Body.Close() // Required by http lib implementation.
}
if err != nil {
// Decode the JSON response into a struct
var status service.StatusMessage
if err := json.NewDecoder(response.Body).Decode(&status); err != nil {
newErr := fmt.Errorf("failure: Execute(%T): err(%s), error decoding response JSON", request, err)
klog.V(4).Info(newErr)
return nil, newErr
}

newErr := fmt.Errorf("failure: Execute(%T): err(%s), uri(%s), details(%s), code(%d), message(%s)",
request, err, status.Uri, status.Details, status.Status.Code, status.Status.Message)
klog.V(4).Info(newErr)
return nil, newErr
newErr := handleServiceError(response, err)
return nil, fmt.Errorf("execute failure(%T): %w", request, newErr)
}

klog.V(3).InfoS("success: ResyncBladeById", "applianceId", applId, "bladeID", blade.GetId())
Expand Down
Loading

0 comments on commit bf8b702

Please sign in to comment.