diff --git a/src/catalog/cacheservice/main.go b/src/catalog/cacheservice/main.go index 467a134f..4a784718 100644 --- a/src/catalog/cacheservice/main.go +++ b/src/catalog/cacheservice/main.go @@ -95,8 +95,12 @@ func NewCacheService(ctx basecontext.ApiContext) (*CacheService, error) { } svc.cacheFolder = cacheFolder - if freeDiskSpace, err := diskspaceservice.Get(ctx).GetCacheDiskSpace(ctx); err == nil { + cacheDiag := errors.NewDiagnostics("CacheService") + freeDiskSpace := diskspaceservice.Get(ctx).GetCacheDiskSpace(ctx, cacheDiag) + if !cacheDiag.HasErrors() { svc.maxCacheSize = svc.cfg.CacheMaxSize(freeDiskSpace) + } else { + ctx.LogErrorf("Failed to get cache disk space: %v", cacheDiag.Errors[0].Message) } return svc, nil diff --git a/src/controllers/cache.go b/src/controllers/cache.go index c3cd865c..edcbd64d 100644 --- a/src/controllers/cache.go +++ b/src/controllers/cache.go @@ -148,7 +148,8 @@ func GetCatalogCacheHandler() restapi.ControllerHandler { } var freeDiskSpace int64 - if ds, err := diskspace.Get(ctx).GetCacheDiskSpace(ctx); err == nil { + localDiag := errors.NewDiagnostics("GetCacheDiskSpaceFallback") + if ds := diskspace.Get(ctx).GetCacheDiskSpace(ctx, localDiag); !localDiag.HasErrors() { freeDiskSpace = ds } else if hwInfo, err := serviceprovider.Get().System.GetHardwareInfo(ctx); err == nil { freeDiskSpace = int64(hwInfo.FreeDiskSize) diff --git a/src/controllers/config.go b/src/controllers/config.go index 910ed92d..a7f4a2eb 100644 --- a/src/controllers/config.go +++ b/src/controllers/config.go @@ -2,14 +2,14 @@ package controllers import ( "encoding/json" - "errors" - "fmt" "net/http" "os" + "strconv" "github.com/Parallels/prl-devops-service/basecontext" "github.com/Parallels/prl-devops-service/config" "github.com/Parallels/prl-devops-service/constants" + prlerrors "github.com/Parallels/prl-devops-service/errors" "github.com/Parallels/prl-devops-service/logs" "github.com/Parallels/prl-devops-service/mappers" "github.com/Parallels/prl-devops-service/models" @@ -104,28 +104,27 @@ func registerConfigHandlers(ctx basecontext.ApiContext, version string) { // @Tags Config // @Produce json // @Success 200 {object} models.ParallelsDesktopLicense -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth -// @Router /v1/parallels_desktop/key [get] +// @Router /v1/config/parallels-desktop/license [get] func GetParallelsDesktopLicenseHandler() restapi.ControllerHandler { return func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() ctx := GetBaseContext(r) defer Recover(ctx, r, w) + getPDLicenseDiag := prlerrors.NewDiagnostics("/config/parallels-desktop/license") provider := serviceprovider.Get() if provider.ParallelsDesktopService == nil || !provider.ParallelsDesktopService.Installed() { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Parallels Desktop is not installed", - Code: http.StatusNotFound, - }) + getPDLicenseDiag.AddError("404", "Parallels Desktop is not installed", "GetParallelsDesktopLicense") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getPDLicenseDiag, http.StatusNotFound)) return } - license, err := provider.ParallelsDesktopService.GetLicense() - if err != nil { - ReturnApiError(ctx, w, models.NewFromError(err)) + license := provider.ParallelsDesktopService.GetLicense(getPDLicenseDiag) + if getPDLicenseDiag.HasErrors() { + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getPDLicenseDiag, http.StatusInternalServerError)) return } @@ -141,7 +140,7 @@ func GetParallelsDesktopLicenseHandler() restapi.ControllerHandler { // @Produce json // @Param installToolsRequest body models.InstallToolsRequest true "Install Tools Request" // @Success 200 {object} models.InstallToolsResponse -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -151,19 +150,16 @@ func Install3rdPartyToolsHandler() restapi.ControllerHandler { defer r.Body.Close() ctx := GetBaseContext(r) defer Recover(ctx, r, w) + installToolsDiag := prlerrors.NewDiagnostics("/config/tools/install") var request models.InstallToolsRequest if err := http_helper.MapRequestBody(r, &request); err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Invalid request body: " + err.Error(), - Code: http.StatusBadRequest, - }) + installToolsDiag.AddError(strconv.Itoa(http.StatusBadRequest), "Invalid request body: "+err.Error(), "MapRequestBody") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(installToolsDiag, http.StatusBadRequest)) return } - if err := request.Validate(); err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Invalid request body: " + err.Error(), - Code: http.StatusBadRequest, - }) + request.Validate(installToolsDiag) + if installToolsDiag.HasErrors() { + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(installToolsDiag, http.StatusBadRequest)) return } @@ -205,7 +201,7 @@ func Install3rdPartyToolsHandler() restapi.ControllerHandler { // @Produce json // @Param uninstallToolsRequest body models.UninstallToolsRequest true "Uninstall Tools Request" // @Success 200 {object} models.InstallToolsResponse -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -215,19 +211,16 @@ func Uninstall3rdPartyToolsHandler() restapi.ControllerHandler { defer r.Body.Close() ctx := GetBaseContext(r) defer Recover(ctx, r, w) + uninstallToolsDiag := prlerrors.NewDiagnostics("/config/tools/uninstall") var request models.UninstallToolsRequest if err := http_helper.MapRequestBody(r, &request); err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Invalid request body: " + err.Error(), - Code: http.StatusBadRequest, - }) + uninstallToolsDiag.AddError(strconv.Itoa(http.StatusBadRequest), "Invalid request body: "+err.Error(), "MapRequestBody") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(uninstallToolsDiag, http.StatusBadRequest)) return } - if err := request.Validate(); err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Invalid request body: " + err.Error(), - Code: http.StatusBadRequest, - }) + request.Validate(uninstallToolsDiag) + if uninstallToolsDiag.HasErrors() { + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(uninstallToolsDiag, http.StatusBadRequest)) return } @@ -265,7 +258,7 @@ func Uninstall3rdPartyToolsHandler() restapi.ControllerHandler { // @Tags Config // @Produce json // @Success 202 -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -286,7 +279,7 @@ func RestartApiHandler() restapi.ControllerHandler { // @Tags Config // @Produce json // @Success 200 {object} models.SystemUsageResponse -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -297,14 +290,25 @@ func GetHardwareInfo() restapi.ControllerHandler { ctx := GetBaseContext(r) cfg := config.Get() defer Recover(ctx, r, w) + getHardwareInfoDiag := prlerrors.NewDiagnostics("/config/hardware") provider := serviceprovider.Get() os := system.Get().GetOperatingSystem() var hardwareInfo *models.SystemUsageResponse - var err error if os == "macos" { - hardwareInfo, err = provider.ParallelsDesktopService.GetHardwareUsage(ctx) + hardwareInfo = provider.ParallelsDesktopService.GetHardwareUsage(ctx, getHardwareInfoDiag) } else { - hardwareInfo, err = provider.System.GetHardwareUsage(ctx) + hardwareInfo = provider.System.GetHardwareUsage(ctx, getHardwareInfoDiag) + } + // 1. First, safely check if the error is what failed + if getHardwareInfoDiag.HasErrors() { + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getHardwareInfoDiag, http.StatusInternalServerError)) + return + } + // 2. ONLY if there was no error do we check if the data is missing! + if hardwareInfo == nil { + getHardwareInfoDiag.AddError("500", "Hardware info not found", "GetHardwareUsage") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getHardwareInfoDiag, http.StatusInternalServerError)) + return } hardwareInfo.EnabledModules = cfg.GetEnabledModules() @@ -334,7 +338,7 @@ func GetHardwareInfo() restapi.ControllerHandler { } var freeDiskSpace int64 - if ds, err := diskspace.Get(ctx).GetCacheDiskSpace(ctx); err == nil { + if ds := diskspace.Get(ctx).GetCacheDiskSpace(ctx, getHardwareInfoDiag); !getHardwareInfoDiag.HasErrors() { freeDiskSpace = ds } else if hwInfo, err := provider.System.GetHardwareInfo(ctx); err == nil { freeDiskSpace = int64(hwInfo.FreeDiskSize) @@ -353,11 +357,6 @@ func GetHardwareInfo() restapi.ControllerHandler { } } - if err != nil || hardwareInfo == nil { - ReturnApiError(ctx, w, models.NewFromError(err)) - return - } - w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(hardwareInfo) } @@ -373,6 +372,8 @@ func GetHardwareInfo() restapi.ControllerHandler { func GetSystemHealth() restapi.ControllerHandler { return func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() + ctx := GetBaseContext(r) + defer Recover(ctx, r, w) provider := serviceprovider.Get() result := models.ApiHealthCheck{} @@ -445,7 +446,7 @@ func GetSystemHealth() restapi.ControllerHandler { // @Tags Config // @Produce plain // @Success 200 -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -455,34 +456,28 @@ func GetSystemLogs() restapi.ControllerHandler { defer r.Body.Close() ctx := GetBaseContext(r) defer Recover(ctx, r, w) - + getSystemLogsDiag := prlerrors.NewDiagnostics("/logs") cfg := config.Get() // Checking if we have the logs to file enabled so we can read the logs if !cfg.GetBoolKey(constants.LOG_TO_FILE_ENV_VAR) && !cfg.GetBoolKey(constants.PRL_DEVOPS_LOG_TO_FILE_ENV_VAR) { - err := errors.New("logs to file is not enabled, we cannot read the logs") - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Failed to read log file: " + err.Error(), - Code: http.StatusBadRequest, - }) + getSystemLogsDiag.AddError(strconv.Itoa(http.StatusBadRequest), "logs to file is not enabled, we cannot read the logs", "GetBoolKey") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getSystemLogsDiag, http.StatusBadRequest)) return } logFile := logs.GetLogFilePath(ctx) if logFile == "" { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Failed to read log file: log file path is empty", - Code: http.StatusBadRequest, - }) + getSystemLogsDiag.AddError(strconv.Itoa(http.StatusBadRequest), "Failed to read log file: log file path is empty", "GetLogFilePath") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getSystemLogsDiag, http.StatusBadRequest)) return } content, err := os.ReadFile(logFile) if err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: fmt.Sprintf("Failed to read log file %s: %v", logFile, err.Error()), - Code: http.StatusBadRequest, - }) + rsp := models.NewFromError(err) + getSystemLogsDiag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "Failed to read log file") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getSystemLogsDiag, rsp.Code)) return } @@ -497,7 +492,7 @@ func GetSystemLogs() restapi.ControllerHandler { // @Tags Config // @Produce json // @Success 101 "Switching Protocols to websocket" -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -569,7 +564,7 @@ func StreamSystemLogs() restapi.ControllerHandler { // @Produce json // @Param createRequest body models.DiskSpaceAvailableRequest false "Disk Space Available Request" // @Success 200 {object} models.DiskSpaceAvailable -// @Failure 400 {object} models.ApiErrorResponse +// @Failure 400 {object} models.ApiErrorDiagnosticsResponse // @Failure 401 {object} models.OAuthErrorResponse // @Security ApiKeyAuth // @Security BearerAuth @@ -579,19 +574,17 @@ func GetParallelsDiskSpace() restapi.ControllerHandler { defer r.Body.Close() ctx := GetBaseContext(r) defer Recover(ctx, r, w) - + getDiskSpaceAvailableDiag := prlerrors.NewDiagnostics("/config/diskspace") var request models.DiskSpaceAvailableRequest if err := http_helper.MapRequestBody(r, &request); err != nil { - ReturnApiError(ctx, w, models.ApiErrorResponse{ - Message: "Invalid request body: " + err.Error(), - Code: http.StatusBadRequest, - }) + getDiskSpaceAvailableDiag.AddError(strconv.Itoa(http.StatusBadRequest), "Invalid request body: "+err.Error(), "MapRequestBody") + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getDiskSpaceAvailableDiag, http.StatusBadRequest)) return } - response, err := diskspace.Get(ctx).GetDiskSpaceAvailable(ctx, request.UserName, request.FolderPath) - if err != nil { - ReturnApiError(ctx, w, models.NewFromError(err)) + response := diskspace.Get(ctx).GetDiskSpaceAvailable(ctx, request.UserName, request.FolderPath, getDiskSpaceAvailableDiag) + if getDiskSpaceAvailableDiag.HasErrors() { + ReturnApiErrorWithDiagnostics(ctx, w, models.NewDiagnosticsWithCode(getDiskSpaceAvailableDiag, http.StatusInternalServerError)) return } diff --git a/src/models/tools.go b/src/models/tools.go index 4ae71156..ef7cbd96 100644 --- a/src/models/tools.go +++ b/src/models/tools.go @@ -1,6 +1,11 @@ package models -import "github.com/Parallels/prl-devops-service/errors" +import ( + "net/http" + "strconv" + + "github.com/Parallels/prl-devops-service/errors" +) type InstallToolsRequest struct { All bool `json:"all"` @@ -13,9 +18,10 @@ type InstallToolsRequestItem struct { Flags map[string]string `json:"flags"` } -func (i *InstallToolsRequest) Validate() error { +func (i *InstallToolsRequest) Validate(diag *errors.Diagnostics) { if i.Tools == nil && !i.All { - return errors.New("tools cannot be empty") + diag.AddError(strconv.Itoa(http.StatusBadRequest), "tools cannot be empty", "Validate") + return } for _, tool := range i.Tools { if tool.Version == "" { @@ -25,8 +31,6 @@ func (i *InstallToolsRequest) Validate() error { tool.Flags = make(map[string]string) } } - - return nil } type InstallToolsResponse struct { @@ -52,17 +56,16 @@ type UninstallToolsRequestItem struct { Flags map[string]string `json:"flags"` } -func (u *UninstallToolsRequest) Validate() error { +func (u *UninstallToolsRequest) Validate(diag *errors.Diagnostics) { if u.Tools == nil && !u.All { - return errors.New("tools cannot be empty") + diag.AddError(strconv.Itoa(http.StatusBadRequest), "tools cannot be empty", "Validate") + return } for _, tool := range u.Tools { if tool.Flags == nil { tool.Flags = make(map[string]string) } } - - return nil } type UninstallToolsResponse struct { diff --git a/src/serviceprovider/diskSpace/main.go b/src/serviceprovider/diskSpace/main.go index cd76c505..232d324f 100644 --- a/src/serviceprovider/diskSpace/main.go +++ b/src/serviceprovider/diskSpace/main.go @@ -2,12 +2,14 @@ package diskspaceservice import ( "context" + "strconv" "sync" "time" "github.com/Parallels/prl-devops-service/basecontext" "github.com/Parallels/prl-devops-service/config" "github.com/Parallels/prl-devops-service/constants" + "github.com/Parallels/prl-devops-service/errors" "github.com/Parallels/prl-devops-service/helpers" "github.com/Parallels/prl-devops-service/models" eventemitter "github.com/Parallels/prl-devops-service/serviceprovider/eventEmitter" @@ -89,16 +91,20 @@ func (d *DiskSpaceService) IsRunning() bool { return d.isRunning } -func (d *DiskSpaceService) GetCacheDiskSpace(ctx basecontext.ApiContext) (int64, error) { +func (d *DiskSpaceService) GetCacheDiskSpace(ctx basecontext.ApiContext, diag *errors.Diagnostics) int64 { cacheFolder, err := config.Get().CatalogCacheFolder() if err != nil { - return 0, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "CatalogCacheFolder") + return 0 } diskSpace, err := helpers.GetFreeDiskSpace(cacheFolder) if err != nil { - return 0, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetFreeDiskSpace") + return 0 } - return diskSpace, nil + return diskSpace } // SetParallelsHomePathProvider injects the function used to query Parallels home disk space. @@ -117,19 +123,21 @@ func (d *DiskSpaceService) getParallelsHomepath(ctx basecontext.ApiContext, user return d.parallelsHomepathFn(ctx, username) } -func (d *DiskSpaceService) GetDiskSpaceAvailable(ctx basecontext.ApiContext, username, folderPath string) (models.DiskSpaceAvailable, error) { +func (d *DiskSpaceService) GetDiskSpaceAvailable(ctx basecontext.ApiContext, username, folderPath string, diag *errors.Diagnostics) models.DiskSpaceAvailable { response := models.DiskSpaceAvailable{} - cacheDiskSpace, err := d.GetCacheDiskSpace(ctx) - if err != nil { - return response, err + cacheDiskSpace := d.GetCacheDiskSpace(ctx, diag) + if diag.HasErrors() { + return response } response.CacheFolder = cacheDiskSpace if folderPath != "" { diskSpace, err := helpers.GetFreeDiskSpace(folderPath) if err != nil { - return response, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetFreeDiskSpace") + return response } response.Given = diskSpace } @@ -142,16 +150,20 @@ func (d *DiskSpaceService) GetDiskSpaceAvailable(ctx basecontext.ApiContext, use parallelsHomeDir, err := d.getParallelsHomepath(ctx, username) if err != nil { - return response, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "getParallelsHomepath") + return response } parallelsHomeDiskSpace, err := helpers.GetFreeDiskSpace(parallelsHomeDir) if err != nil { - return response, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetFreeDiskSpace") + return response } response.ParallelsHome = parallelsHomeDiskSpace response.PrlHomePath = folderPath response.PrlHomePath = parallelsHomeDir - return response, nil + return response } func (d *DiskSpaceService) startDiskspaceWorker() { @@ -178,10 +190,10 @@ func (d *DiskSpaceService) CheckDiskSpaceAndBroadcast() { } event := models.DiskSpaceAvailable{} - - cacheDiskSpace, err := d.GetCacheDiskSpace(d.ctx) - if err != nil { - d.ctx.LogErrorf("[DiskSpace] [worker] Error getting cache disk space: %v", err) + workerDiag := errors.NewDiagnostics("BackgroundWorker") + cacheDiskSpace := d.GetCacheDiskSpace(d.ctx, workerDiag) + if workerDiag.HasErrors() { + d.ctx.LogErrorf("[DiskSpace] [worker] Error getting cache disk space: %v", workerDiag.Errors[0].Message) } else { d.ctx.LogInfof("[DiskSpace] [worker] Cache disk space available: %d MB", cacheDiskSpace) event.CacheFolder = cacheDiskSpace diff --git a/src/serviceprovider/parallelsdesktop/license.go b/src/serviceprovider/parallelsdesktop/license.go index 6d3e38cf..64d5f268 100644 --- a/src/serviceprovider/parallelsdesktop/license.go +++ b/src/serviceprovider/parallelsdesktop/license.go @@ -2,6 +2,7 @@ package parallelsdesktop import ( "encoding/json" + "strconv" "strings" "github.com/Parallels/prl-devops-service/errors" @@ -10,7 +11,7 @@ import ( "github.com/cjlapao/common-go/helper" ) -func (s *ParallelsService) GetLicense() (*models.ParallelsDesktopLicense, error) { +func (s *ParallelsService) GetLicense(diag *errors.Diagnostics) *models.ParallelsDesktopLicense { getLicenseCmd := helpers.Command{ Command: s.serverExecutable, Args: []string{"info", "--license", "--json"}, @@ -18,7 +19,9 @@ func (s *ParallelsService) GetLicense() (*models.ParallelsDesktopLicense, error) output, _, _, err := helpers.ExecuteWithOutput(s.ctx.Context(), getLicenseCmd, helpers.ExecutionTimeout) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "ExecuteWithOutput") + return nil } output = strings.ReplaceAll(output, "This feature is not available in this edition of Parallels Desktop. \n", "") @@ -26,10 +29,12 @@ func (s *ParallelsService) GetLicense() (*models.ParallelsDesktopLicense, error) var license models.ParallelsDesktopLicense err = json.Unmarshal([]byte(output), &license) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "Unmarshal") + return nil } - return &license, nil + return &license } func (s *ParallelsService) InstallLicense(licenseKey, username, password string) error { diff --git a/src/serviceprovider/parallelsdesktop/main.go b/src/serviceprovider/parallelsdesktop/main.go index 0c4f5d67..d03277f7 100644 --- a/src/serviceprovider/parallelsdesktop/main.go +++ b/src/serviceprovider/parallelsdesktop/main.go @@ -2822,7 +2822,7 @@ func (s *ParallelsService) RunCustomCommand(ctx basecontext.ApiContext, vm *mode return nil } -func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models.SystemUsageResponse, error) { +func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext, diag *errors.Diagnostics) *models.SystemUsageResponse { result := &models.SystemUsageResponse{ TotalInUse: &models.SystemUsageItem{}, TotalReserved: &models.SystemUsageItem{}, @@ -2832,7 +2832,9 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models vms, err := s.GetCachedVms(ctx, "") if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetCachedVms") + return nil } for _, vm := range vms { @@ -2843,13 +2845,17 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models result.TotalInUse.LogicalCpuCount += vm.Hardware.CPU.Cpus memorySizeInt, err := helpers.GetSizeByteFromString(vm.Hardware.Memory.Size) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetSizeByteFromString") + return nil } result.TotalInUse.MemorySize += helpers.ConvertByteToMegabyte(memorySizeInt) if vm.Hardware.Hdd0.Size != "" { hddSizeInt, err := helpers.GetSizeByteFromString(vm.Hardware.Hdd0.Size) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetSizeByteFromString") + return nil } result.TotalInUse.DiskSize += helpers.ConvertByteToMegabyte(hddSizeInt) } @@ -2860,13 +2866,17 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models result.TotalReserved.LogicalCpuCount += vm.Hardware.CPU.Cpus memorySizeInt, err := helpers.GetSizeByteFromString(vm.Hardware.Memory.Size) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetSizeByteFromString") + return nil } result.TotalReserved.MemorySize += helpers.ConvertByteToMegabyte(memorySizeInt) if vm.Hardware.Hdd0.Size != "" { hddSizeInt, err := helpers.GetSizeByteFromString(vm.Hardware.Hdd0.Size) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetSizeByteFromString") + return nil } result.TotalReserved.DiskSize += helpers.ConvertByteToMegabyte(hddSizeInt) } @@ -2878,7 +2888,9 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models systemSrv := system.Get() systemInfo, err := systemSrv.GetHardwareInfo(ctx) if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetHardwareInfo") + return nil } result.CpuType = systemInfo.CpuType result.CpuBrand = systemInfo.CpuBrand @@ -2904,7 +2916,9 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models homeDir, err := s.GetUserHome(ctx, "") if err != nil { - return nil, err + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetUserHome") + return nil } result.TotalAvailable.PrlHomeTotalSize, _ = helpers.GetTotalDiskSpace(homeDir) @@ -2918,7 +2932,7 @@ func (s *ParallelsService) GetHardwareUsage(ctx basecontext.ApiContext) (*models } result.OsName = systemSrv.GetOSName() - return result, nil + return result } func (s *ParallelsService) RegenerateMacAddress(ctx basecontext.ApiContext, vmID string, owner string) error { // getting the VM to check state diff --git a/src/serviceprovider/system/main.go b/src/serviceprovider/system/main.go index 4b5a5320..fbeb3343 100644 --- a/src/serviceprovider/system/main.go +++ b/src/serviceprovider/system/main.go @@ -752,11 +752,13 @@ func (s *SystemService) getLinuxArchitecture(ctx basecontext.ApiContext) (string return strings.ReplaceAll(cpuType, "\n", ""), nil } -func (s *SystemService) GetHardwareUsage(ctx basecontext.ApiContext) (*models.SystemUsageResponse, error) { +func (s *SystemService) GetHardwareUsage(ctx basecontext.ApiContext, diag *errors.Diagnostics) *models.SystemUsageResponse { result := &models.SystemUsageResponse{} arch, err := s.GetArchitecture(ctx) if err != nil { + rsp := models.NewFromError(err) + diag.AddError(strconv.Itoa(rsp.Code), rsp.Message, "GetArchitecture") arch = err.Error() } @@ -796,7 +798,7 @@ func (s *SystemService) GetHardwareUsage(ctx basecontext.ApiContext) (*models.Sy } } - return result, nil + return result } func (s *SystemService) GetExternalIp(ctx basecontext.ApiContext) (string, error) {