Skip to content

Commit

Permalink
Optimize the client error messages (#26)
Browse files Browse the repository at this point in the history
* fix: optimize the client errors in cfm-service

* feat: pass the client errors to cfm-webui

* fix: reset the port in compose memory popup

* feat: only display the http code after the client error
  • Loading branch information
Meng-20 authored Aug 27, 2024
1 parent 3bc589e commit 643f744
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 205 deletions.
211 changes: 83 additions & 128 deletions pkg/common/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,70 +25,61 @@ type StatusCodeType int
// can be used programmatically by clients to differentiate various errors returned.
// More error code will be added
const (
StatusOK StatusCodeType = iota
StatusCreatedSuccess //201
StatusComposePartialSuccess //206
StatusApplianceResyncPartialSuccess //206
StatusOK StatusCodeType = iota

StatusComposePartialSuccess //206
StatusApplianceResyncPartialSuccess //206

StatusAppliancesExceedMaximum //422
StatusBladesExceedMaximum //422
StatusHostsExceedMaximum //422

StatusInvalidBackend //400: StatusBadRequest
StatusApplianceComposeMemoryRequestBad //400
StatusApplianceIdMismatch //400
StatusResourceNotEnough //400
StatusEndpointNotConnected //400
StatusBackendInterfaceFailure //500: StatusInternalServerError
StatusBackendInterfaceFailure //500: StatusInternalServerError

StatusComposeMemoryFailure //409: StatusConflict
StatusComposeMemoryByResourceFailure //409
StatusAssignMemoryFailure //409
StatusUnassignMemoryFailure //409
StatusHostGetMemoryFailure //409
StatusApplianceGetMemoryFailure //409
StatusApplianceGetMemoryByIdFailure //409
StatusHostGetMemoryByIdFailure //409
StatusApplianceFreeMemoryFailure //409
StatusHostFreeMemoryFailure //409
StatusGetMemoryResourceBlocksFailure //409
StatusGetMemoryResourceBlockByIdFailure //409
StatusApplianceGetPortsFailure //409
StatusHostGetPortsFailure //409
StatusGetPortDetailsFailure //409
StatusGetMemoryDevicesFailure //409
StatusGetMemoryDevicesDetailsFailure //409
StatusApplianceResyncFailure //409
StatusComposeMemoryByResourceFailure //409

StatusApplianceNameDoesNotExist //404: StatusNotFound
StatusBladeIdDoesNotExist //404
StatusApplianceCreateSessionFailure //500
StatusApplianceDeleteSessionFailure //500
StatusApplianceIdDoesNotExist //404
StatusAssignMemoryFailure //409
StatusUnassignMemoryFailure //409

StatusHostGetMemoryFailure //409
StatusBladeGetMemoryFailure //409
StatusBladeGetMemoryByIdFailure //409
StatusHostGetMemoryByIdFailure //409
StatusBladeFreeMemoryFailure //409
StatusHostFreeMemoryFailure //409

StatusHostNameDoesNotExist //404
StatusHostCreateSessionFailure //500
StatusHostDeleteSessionFailure //500
StatusApplianceGetResourcesFailure //500
StatusApplianceGetResourceFailure //500
StatusApplianceGetEndpointsFailure //500
StatusApplianceGetOneEndpointFailure //500
StatusApplianceUnassginMemoryFailure //500
StatusApplianceUnallocateMemoryFailure //500
StatusBladeGetMemoryResourceBlocksFailure //409
StatusBladeGetMemoryResourceBlockDetailsFailure //409
StatusBladeGetPortsFailure //409
StatusHostGetPortsFailure //409
StatusGetPortDetailsFailure //409
StatusGetMemoryDevicesFailure //409
StatusGetMemoryDevicesDetailsFailure //409

StatusHostIdDoesNotExist //404
StatusApplianceResyncFailure //409

StatusApplianceIdDuplicate //409
StatusBladeIdDuplicate //409
StatusMemoryIdDuplicate //409
StatusPortIdDuplicate //409
StatusHostIdDuplicate //409

StatusApplianceCreateSessionFailure //500
StatusApplianceDeleteSessionFailure //500
StatusBladeCreateSessionFailure //500
StatusBladeDeleteSessionFailure //500
StatusHostCreateSessionFailure //500
StatusHostDeleteSessionFailure //500

StatusApplianceIdDoesNotExist //404
StatusBladeIdDoesNotExist //404
StatusHostIdDoesNotExist //404
StatusMemoryIdDoesNotExist //404
StatusPortIdDoesNotExist //404
StatusResourceIdDoesNotExist //404
StatusMemoryDeviceIdDoesNotExist //404
StatusNoCapacityInBlock //404

StatusEndpointDoesNotExist //404
StatusSessionDoesNotExist //404

StatusManagerInitializationFailure //500

)

// Return a string representation of our StatusType. When this value is printed as a
Expand All @@ -97,32 +88,26 @@ func (e StatusCodeType) String() string {
switch e {
case StatusOK:
return "Success"
case StatusCreatedSuccess:
return "Created Successfully"
case StatusComposePartialSuccess:
return "Compose Partial Success"
case StatusApplianceResyncPartialSuccess:
return "Appliance Resync Partial Success"
case StatusComposeMemoryFailure:
return "Compose Memory Failed"
case StatusComposeMemoryByResourceFailure:
return "Compose Memory By Resource Failed"
case StatusAssignMemoryFailure:
return "Assign Memory Failed"
case StatusUnassignMemoryFailure:
return "Unassign Memory Failed"
case StatusApplianceNameDoesNotExist:
return "Appliance Name does not exist"
case StatusHostNameDoesNotExist:
return "Host Name does not exist"
case StatusInvalidBackend:
return "Backend interface does not exist"
case StatusBackendInterfaceFailure:
return "Backend Interface does not exist"
case StatusApplianceCreateSessionFailure:
return "Appliance Create Session Failure"
case StatusApplianceDeleteSessionFailure:
return "Appliance Delete Session Failure"
case StatusBladeCreateSessionFailure:
return "Blade Create Session Failure"
case StatusBladeDeleteSessionFailure:
return "Blade Delete Session Failure"
case StatusApplianceIdDoesNotExist:
return "Appliance Id Does Not Exist"
case StatusHostCreateSessionFailure:
Expand All @@ -137,24 +122,24 @@ func (e StatusCodeType) String() string {
return "Port Id Does Not Exist"
case StatusResourceIdDoesNotExist:
return "Resource Id Does Not Exist"
case StatusApplianceGetMemoryFailure:
return "Appliance Get Memory Failure"
case StatusBladeGetMemoryFailure:
return "Blade Get Memory Failure"
case StatusHostGetMemoryFailure:
return "Host Get Memory Failure"
case StatusApplianceGetMemoryByIdFailure:
return "Appliance Get Memory By Id Failure"
case StatusBladeGetMemoryByIdFailure:
return "Blade Get Memory By Id Failure"
case StatusHostGetMemoryByIdFailure:
return "Host Get Memory By Id Failure"
case StatusApplianceFreeMemoryFailure:
return "Appliance Free Memory Failure"
case StatusBladeFreeMemoryFailure:
return "Blade Free Memory Failure"
case StatusHostFreeMemoryFailure:
return "Host Free Memory Failure"
case StatusGetMemoryResourceBlocksFailure:
return "Appliance Get Memory Resource Blocks Failure"
case StatusGetMemoryResourceBlockByIdFailure:
return "Appliance Get Memory Resource Block By Id Failure"
case StatusApplianceGetPortsFailure:
return "Appliance Get Ports Failure"
case StatusBladeGetMemoryResourceBlocksFailure:
return "Blade Get Memory Resource Blocks Failure"
case StatusBladeGetMemoryResourceBlockDetailsFailure:
return "Blade Get Memory Resource Block By Id Failure"
case StatusBladeGetPortsFailure:
return "Blade Get Ports Failure"
case StatusHostGetPortsFailure:
return "Host Get Ports Failure"
case StatusGetPortDetailsFailure:
Expand All @@ -165,32 +150,6 @@ func (e StatusCodeType) String() string {
return "Get Memory Devices Details Failure"
case StatusApplianceResyncFailure:
return "Appliance Resync Failure"
case StatusResourceNotEnough:
return "Resource Not Enough"
case StatusSessionDoesNotExist:
return "Session Does Not Exist"
case StatusApplianceGetResourceFailure:
return "Appliance Get A Specific Resource Failure"
case StatusApplianceGetResourcesFailure:
return "Appliance Get Resources Failure"
case StatusNoCapacityInBlock:
return "No Capacity In Block"
case StatusEndpointDoesNotExist:
return "Appliance Does Not Exist"
case StatusApplianceGetEndpointsFailure:
return "Appliance Get Endpoints Failure"
case StatusApplianceGetOneEndpointFailure:
return "Appliance Get One Endpoint Failure"
case StatusApplianceIdMismatch:
return "Appliance Id Mismatch"
case StatusApplianceComposeMemoryRequestBad:
return "Appliance Compose Memory Request Empty"
case StatusEndpointNotConnected:
return "Endpoint Not Connected"
case StatusApplianceUnassginMemoryFailure:
return "Appliance Unassgin Memory Failure"
case StatusApplianceUnallocateMemoryFailure:
return "Appliance Unallocate Memory Failure"
case StatusBladeIdDoesNotExist:
return "Blade Id Does Not Exist"
case StatusAppliancesExceedMaximum:
Expand All @@ -201,6 +160,16 @@ func (e StatusCodeType) String() string {
return "Maximum Host count exceeded"
case StatusManagerInitializationFailure:
return "Manager Initialization Failure"
case StatusApplianceIdDuplicate:
return "Appliance Id Already Exists"
case StatusBladeIdDuplicate:
return "Blade Id Already Exists"
case StatusMemoryIdDuplicate:
return "Memory Id Already Exist"
case StatusPortIdDuplicate:
return "Port Id Already Exist"
case StatusHostIdDuplicate:
return "Host Id Already Exist"
}
return "Unknown"

Expand All @@ -212,60 +181,46 @@ func (e StatusCodeType) HttpStatusCode() int {
switch e {
case StatusOK:
return http.StatusOK // 200
case StatusCreatedSuccess:
return http.StatusCreated // 201
case StatusComposePartialSuccess,
StatusApplianceResyncPartialSuccess:
return http.StatusPartialContent // 206
case StatusInvalidBackend,
StatusApplianceComposeMemoryRequestBad,
StatusApplianceIdMismatch,
StatusResourceNotEnough,
StatusEndpointNotConnected,
StatusBladeIdDoesNotExist:
return http.StatusBadRequest // 400
case StatusApplianceNameDoesNotExist,
case StatusBladeIdDoesNotExist,
StatusApplianceIdDoesNotExist,
StatusHostNameDoesNotExist,
StatusHostIdDoesNotExist,
StatusMemoryIdDoesNotExist,
StatusPortIdDoesNotExist,
StatusResourceIdDoesNotExist,
StatusEndpointDoesNotExist,
StatusMemoryDeviceIdDoesNotExist,
StatusNoCapacityInBlock,
StatusSessionDoesNotExist:
StatusMemoryDeviceIdDoesNotExist:
return http.StatusNotFound // 404
case StatusComposeMemoryFailure,
StatusComposeMemoryByResourceFailure,
case StatusComposeMemoryByResourceFailure,
StatusAssignMemoryFailure,
StatusUnassignMemoryFailure,
StatusHostGetMemoryFailure,
StatusApplianceGetMemoryFailure,
StatusApplianceGetMemoryByIdFailure,
StatusBladeGetMemoryFailure,
StatusBladeGetMemoryByIdFailure,
StatusHostGetMemoryByIdFailure,
StatusApplianceFreeMemoryFailure,
StatusBladeFreeMemoryFailure,
StatusHostFreeMemoryFailure,
StatusGetMemoryResourceBlocksFailure,
StatusGetMemoryResourceBlockByIdFailure,
StatusApplianceGetPortsFailure,
StatusBladeGetMemoryResourceBlocksFailure,
StatusBladeGetMemoryResourceBlockDetailsFailure,
StatusBladeGetPortsFailure,
StatusHostGetPortsFailure,
StatusGetPortDetailsFailure,
StatusGetMemoryDevicesFailure,
StatusGetMemoryDevicesDetailsFailure,
StatusApplianceResyncFailure:
StatusApplianceResyncFailure,
StatusApplianceIdDuplicate,
StatusBladeIdDuplicate,
StatusPortIdDuplicate,
StatusHostIdDuplicate:
return http.StatusConflict // 409
case StatusBackendInterfaceFailure,
StatusApplianceCreateSessionFailure,
StatusApplianceDeleteSessionFailure,
StatusBladeCreateSessionFailure,
StatusBladeDeleteSessionFailure,
StatusHostCreateSessionFailure,
StatusHostDeleteSessionFailure,
StatusApplianceGetResourcesFailure,
StatusApplianceGetResourceFailure,
StatusApplianceGetEndpointsFailure,
StatusApplianceGetOneEndpointFailure,
StatusApplianceUnassginMemoryFailure,
StatusApplianceUnallocateMemoryFailure,
StatusApplianceCreateSessionFailure,
StatusApplianceDeleteSessionFailure,
StatusManagerInitializationFailure:
return http.StatusInternalServerError // 500
case StatusAppliancesExceedMaximum,
Expand Down
22 changes: 12 additions & 10 deletions pkg/manager/appliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func NewAppliance(ctx context.Context, id string) (*Appliance, error) {
// Check for duplicate ID
_, exists := deviceCache.GetApplianceByIdOk(applianceId)
if exists {
return nil, fmt.Errorf("invalid id: applianceId [%s] already exists in cfm-service", applianceId)
newErr := fmt.Errorf("invalid id: applianceId [%s] already exists in cfm-service", applianceId)
return nil, &common.RequestError{StatusCode: common.StatusApplianceIdDuplicate, Err: newErr}
}

a := Appliance{
Expand Down Expand Up @@ -93,7 +94,7 @@ func (a *Appliance) AddBlade(ctx context.Context, c *openapi.Credentials) (*Blad
if err != nil || response == nil {
newErr := fmt.Errorf("create session failure at [%s:%d] using interface [%s]: %w", c.IpAddress, c.Port, backendName, err)
logger.Error(newErr, "failure: add blade")
return nil, &common.RequestError{StatusCode: common.StatusApplianceCreateSessionFailure, Err: newErr}
return nil, &common.RequestError{StatusCode: common.StatusBladeCreateSessionFailure, Err: newErr}
}

bladeId := c.CustomId
Expand All @@ -113,12 +114,12 @@ func (a *Appliance) AddBlade(ctx context.Context, c *openapi.Credentials) (*Blad
if err != nil || response == nil {
newErr := fmt.Errorf("failed to delete session [%s:%d] after failed duplicate bladeId [%s] check: %w", c.IpAddress, c.Port, bladeId, err)
logger.Error(newErr, "failure: add blade")
return nil, &common.RequestError{StatusCode: common.StatusApplianceDeleteSessionFailure, Err: newErr}
return nil, &common.RequestError{StatusCode: common.StatusBladeDeleteSessionFailure, Err: newErr}
}

newErr := fmt.Errorf("invalid id: bladeId [%s] already exists on appliance [%s] ", bladeId, a.Id)
logger.Error(newErr, "failure: add blade")
return nil, &common.RequestError{StatusCode: common.StatusManagerInitializationFailure, Err: newErr}
return nil, &common.RequestError{StatusCode: common.StatusBladeIdDuplicate, Err: newErr}
}

// Create the new Blade
Expand All @@ -134,11 +135,11 @@ func (a *Appliance) AddBlade(ctx context.Context, c *openapi.Credentials) (*Blad
blade, err := NewBlade(ctx, &r)
if err != nil || blade == nil {
req := backend.DeleteSessionRequest{}
response, err := ops.DeleteSession(ctx, &settings, &req)
if err != nil || response == nil {
response, deleErr := ops.DeleteSession(ctx, &settings, &req)
if deleErr != nil || response == nil {
newErr := fmt.Errorf("failed to delete session [%s:%d] after failed blade [%s] object creation: %w", c.IpAddress, c.Port, bladeId, err)
logger.Error(newErr, "failure: add blade")
return nil, &common.RequestError{StatusCode: common.StatusApplianceDeleteSessionFailure, Err: newErr}
return nil, &common.RequestError{StatusCode: common.StatusBladeDeleteSessionFailure, Err: newErr}
}

newErr := fmt.Errorf("appliance [%s] new blade object creation failure: %w", a.Id, err)
Expand Down Expand Up @@ -178,8 +179,9 @@ func (a *Appliance) DeleteBladeById(ctx context.Context, bladeId string) (*Blade
// query for blade
blade, ok := a.Blades[bladeId]
if !ok {
logger.V(2).Info("blade not found during delete: do nothing", "bladeId", bladeId, "applianceId", a.Id)
return &Blade{Id: bladeId}, nil
logger.V(2).Info("blade not found during delete:", "bladeId", bladeId, "applianceId", a.Id)
newErr := fmt.Errorf("blade [%s] not found during delete", bladeId)
return nil, &common.RequestError{StatusCode: common.StatusBladeIdDoesNotExist, Err: newErr}
}

// get blade backend
Expand All @@ -198,7 +200,7 @@ func (a *Appliance) DeleteBladeById(ctx context.Context, bladeId string) (*Blade
logger.V(2).Info("force blade deletion after backend session failure", "bladeId", blade.Id, "applianceId", a.Id)
delete(a.Blades, blade.Id)

return nil, &common.RequestError{StatusCode: common.StatusApplianceDeleteSessionFailure, Err: newErr}
return nil, &common.RequestError{StatusCode: common.StatusBladeDeleteSessionFailure, Err: newErr}
}

// delete blade
Expand Down
Loading

0 comments on commit 643f744

Please sign in to comment.