framework,api,server,ui: improve error messaging#12336
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12336 +/- ##
============================================
+ Coverage 18.93% 18.96% +0.03%
- Complexity 18471 18533 +62
============================================
Files 6221 6223 +2
Lines 560045 560464 +419
Branches 68289 68339 +50
============================================
+ Hits 106048 106296 +248
- Misses 442372 442517 +145
- Partials 11625 11651 +26
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
86379b7 to
c938bd1
Compare
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
|
@blueorangutan package |
|
@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16743 |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
|
@blueorangutan package |
|
@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 18426 |
There was a problem hiding this comment.
Pull request overview
This PR introduces a framework for contextual, consistent, and localizable API error messages across CloudStack server-side exceptions and the UI, backed by a centralized error-messages.json template file and metadata propagation.
Changes:
- Add an error-message resolution pipeline (
ResponseMessageResolver,Exceptionshelpers) and extend API exception responses witherrortextkey+errormetadata. - Propagate richer error context (notably resource-limit details) via
CallContextso errors can be templated/expanded consistently. - Update UI notifications to prefer localized templates when
errortextkey/errormetadataare present; add packaging + tooling support for the new error-messages file.
Reviewed changes
Copilot reviewed 40 out of 41 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/src/main/java/com/cloud/utils/StringUtils.java | Adds a small null-safe string helper. |
| utils/src/main/java/com/cloud/utils/exception/CloudRuntimeException.java | Adds message-key and metadata fields to runtime exceptions. |
| ui/src/utils/plugins.js | Adds localization-aware error notification handling and a locale error utility plugin. |
| ui/src/main.js | Registers the new UI locale error plugin. |
| test/integration/smoke/test_vm_strict_host_tags.py | Updates assertions to new “Instance” wording (contains a syntax issue). |
| test/integration/smoke/test_deploy_vm_root_resize.py | Updates expected error text for root disk size validations (contains logic/scope issues). |
| server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java | Adjusts mocks for UUID usage in new error handling paths. |
| server/src/test/java/org/apache/cloudstack/storage/sharedfs/SharedFSServiceImplTest.java | Updates isRootAdmin mocking signature expectations. |
| server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java | Migrates assertions toward messageKey usage (one assertion still checks getMessage()). |
| server/src/test/java/com/cloud/storage/StorageManagerImplTest.java | Refactors imports + updates admin-check mocking signature. |
| server/src/test/java/com/cloud/storage/snapshot/SnapshotManagerImplTest.java | Refactors imports + updates admin-check mocking signature. |
| server/src/main/java/com/cloud/user/AccountManagerImpl.java | Adds isRootAdmin(Account) overload and reuses it from isRootAdmin(Long). |
| server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java | Populates CallContext error-context metadata for resource-limit errors. |
| server/src/main/java/com/cloud/api/ResponseObjectTypeAdapter.java | Serializes ExceptionResponse via Gson helper and strips uuidList. |
| server/src/main/java/com/cloud/api/ApiServer.java | Injects ResponseMessageResolver into API error serialization path. |
| server/src/main/java/com/cloud/api/ApiAsyncJobDispatcher.java | Ensures async-job error responses are enriched with messageKey/metadata when available. |
| scripts/util/error_messages_tool.py | Adds a utility to audit/fix/sort/find-unused keys in the error-messages JSON. |
| pom.xml | Excludes the generated/managed error-messages file from checks (e.g., RAT). |
| plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java | Adds stub for new isRootAdmin(Account) API in test mock. |
| packaging/el8/cloud.spec | Installs error-messages.json into management config packaging. |
| framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java | Normalizes CloudRuntimeException metadata before job serialization. |
| engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java | Renames displayname field/accessors to displayName. |
| engine/schema/src/main/java/com/cloud/user/UserVO.java | Minor toString() formatting change + import order. |
| engine/schema/src/main/java/com/cloud/user/UserAccountVO.java | Minor toString() formatting change. |
| engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java | Minor toString() formatting change. |
| engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java | Updates tests to assert messageKey-based errors. |
| engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java | Aligns to new VMEntityVO.setDisplayName() method. |
| engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java | Converts many runtime/parameter exceptions to key+metadata-based exceptions via Exceptions.*. |
| debian/cloudstack-management.install | Installs error-messages.json in Debian packaging. |
| client/conf/error-messages.json.in | Adds the initial error message template catalog (contains template/typo issues). |
| api/src/test/java/org/apache/cloudstack/context/ResponseMessageResolverTest.java | Adds unit tests for resolver expansion/metadata handling. |
| api/src/main/java/org/apache/cloudstack/error/Exceptions.java | Adds helpers to construct exceptions with resolved messageKey/metadata. |
| api/src/main/java/org/apache/cloudstack/context/ResponseMessageResolver.java | Adds template loading, metadata merging, and message expansion logic. |
| api/src/main/java/org/apache/cloudstack/context/CallContext.java | Adds error-context storage + root-admin detection helper. |
| api/src/main/java/org/apache/cloudstack/api/response/ExceptionResponse.java | Extends API error response with errortextkey and errormetadata. |
| api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java | Maps resource-limit allocation exceptions to stable error keys. |
| api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java | Converts numeric parsing failure to key+metadata InvalidParameterValueException. |
| api/src/main/java/com/cloud/user/AccountService.java | Adds isRootAdmin(Account) to the public account service interface. |
| api/src/main/java/com/cloud/configuration/Resource.java | Adds a display name to ResourceType for better user-facing messaging. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| except Exception as e | ||
| self.assertTrue("Unable to orchestrate the start of Instance" in str(e)) |
| ) | ||
| except Exception as ex: | ||
| if "rootdisksize override (" + str(newrootsize) + " GB) is smaller than template size" in str(ex): | ||
| success = True | ||
| else: | ||
| self.debug("Virtual machine create did not fail appropriately. Error was actually : " + str(ex)); | ||
| success = True | ||
| else: | ||
| self.debug("Virtual machine create did not fail appropriately. Error was actually : " + str(ex)) |
| userVmManagerImpl.unmanageUserVM(vmId, null); | ||
| }); | ||
| assertEquals("Instance: test-vm is not running or stopped, cannot be unmanaged", exception.getMessage()); | ||
| assertEquals("vm.unmanage.vm.not.right.state", exception.getMessage()); | ||
| verify(userVmDao, times(1)).releaseFromLockTable(vmId); |
| if (params && params.constructor === Object) { | ||
| for (const paramKey in params) { | ||
| localeMsg = localeMsg.replace(`{{${paramKey}}}`, params[paramKey]) | ||
| } | ||
| } |
| "vm.updatenic.work.nic.not.found": "Unable to update NIC as the specified NIC is not found.", | ||
| "vm.updatenic.work.nic.not.found.admin": "Unable to update NIC as the specified NIC ID: {{nicId} is not found.", | ||
| "vm.updatenic.zone.basic.not.allowed": "Zone {{zone}}, has a NetworkType of Basic. Can't change default NIC on a Basic Network.", |
| "vm.scale.reconfigure.answer.failed": "Unable to scale Instance: {{error}}.", | ||
| "vm.scale.root.volume.change.failed": "Failed to change disk offering of the root volume.", | ||
| "vm.scale.source.host.not.found": "Unable to find source host for Instance scaling migration.", | ||
| "vm.scale.up.required": "While the VM is running, only scalling up it is supported. New service offering {{newOffering}} should have at least one value (ram, speed or cpu) greater than the current values {{currentOffering}}.", |
| "vm.upgrade.storage.shared.to.local": "Unable to upgrade Instance {{instance}}: target service offering uses shared storage but the volume is in a local storage pool.", | ||
| "vm.upgrade.system.use.mismatch": "Unable to upgrade Instance: the system use property differs between the current and new service offering.", | ||
| "vm.upgrade.vm.not.right.state": "Unable to upgrade Instance {{instance}} in state {{instanceState}}; make sure the Instance is stopped.", | ||
| "vm.upgrade.vm.sunning.scale.down.unsupported": "Scaling down is not supported while the VM is running. The new service offering attributes {\"memory\": {{newMemory}}, \"CPU speed\": {{newSpeed}}, \"vCPUs\": {{newCPU}}} must not be lower than the current values {\"memory\": {{currentMemory}}, \"CPU speed\": {{currentSpeed}}, \"vCPUs\": {{currentCPU}}}.", |
Description
Framework level improvements for for contextual and localized API error messages
Design spec: Error Message Consistency, Customization, and Localization Framework
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
Refined error message with additional context for admin

User facing error, with localization

Example API response
How Has This Been Tested?
How did you try to break this feature and the system with this change?