This document is a grounding note, not the CLI contract.
Use it when dsctl error translation depends on how DolphinScheduler 3.4.1
actually reports failures.
These notes were grounded in a local checkout of upstream Apache
DolphinScheduler source. During development that checkout is usually mounted at
references/dolphinscheduler, but references/ is ignored, not packaged, and
not required for installed CLI usage.
Representative upstream paths:
references/dolphinscheduler/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.javareferences/dolphinscheduler/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/Result.javareferences/dolphinscheduler/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/exceptions/ServiceException.javareferences/dolphinscheduler/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/exceptions/ApiExceptionHandler.java
DS API failures do not live in one place. The relevant layers are:
- HTTP transport status Examples include login interception and rate limiting.
Result<T>envelope Most API responses carrycode,msg, anddata.Statusenum This is the main catalog of DS API result codes.- Bare
ServiceException("...")sites Some upstream failures bypass namedStatusconstants.
For dsctl, this means upstream error translation cannot rely on status codes
alone. HTTP-only failures and string-only failures also exist.
The primary upstream catalog is Status.java.
Current source inventory facts:
- it contains hundreds of named API result codes
- many business failures raised through
ServiceException(Status.X)becomeResult.code/msg - it is the right baseline for translation coverage planning
But it is not a perfect public contract:
- some numeric codes are reused by multiple names
- some failures use bare
ServiceException("...") - some failures bypass
Resultand use direct HTTP status control
So the correct design stance is:
- treat
Status.javaas the main inventory - do not treat it as the only truth
dsctl should translate at the service boundary, not in transport or output.
The intended split is:
- client/generated/upstream preserve upstream facts
- services map known upstream failures into stable CLI error types
- output serializes the stable CLI envelope
When a service translates one remote error into a stable CLI error type, the
CLI should still preserve the original remote facts separately. The current
error envelope uses error.source for that role instead of overloading
error.details.
Translation should be keyed by service operation, not by raw status code alone.
Why:
- the same DS code may appear in multiple resource contexts
- duplicate numeric codes exist upstream
- actionable suggestions depend on the attempted operation
In practice, the useful unit is:
project.getuser.listschedule.createworkflow-instance.execute-task
not just:
3000150003
The CLI error envelope separates stable CLI semantics from preserved remote facts.
The intended split is:
error.type,error.message, anderror.suggestionexpress stable CLI meaningerror.detailscarries command or resource contexterror.sourcecarries machine-readable origin facts from the underlying remote failure when they are available
For DS remote failures, error.source currently uses:
kind = "remote"system = "dolphinscheduler"layer = "result"plusresult_codeandresult_message, orlayer = "http"plusstatus_code
This lets dsctl translate known failures into stable CLI categories without
discarding the original DS result code or message.
Implementation rule:
- when translating one caught remote exception into a new CLI error, raise the
translated error with
from error - this preserves the exception chain so
error.sourcecan still expose the original remote facts - if a remote error is intentionally left raw, return or raise the original
ApiResultErrororApiHttpErrordirectly
Use the checked-in inventory script to rebuild the upstream baseline:
python tools/extract_ds_api_error_inventory.py --format summary
python tools/extract_ds_api_error_inventory.py --format json --output build/ds-api-error-inventory.json
python tools/extract_ds_api_error_inventory.py --format markdown --output build/ds-api-error-inventory.mdThe script extracts:
- named
Statusentries - duplicate numeric codes
- bare
ServiceException("...")sites - direct
response.setStatus(...)sites
This is an inventory tool, not a translation matrix. The translation matrix
still belongs in handwritten dsctl service logic.
Use the dsctl audit script to inspect current handwritten translation
coverage:
python tools/audit_dsctl_error_translation.py --format summary
python tools/audit_dsctl_error_translation.py --format markdown --output build/dsctl-error-translation-audit.mdThe audit reports:
- which service modules define translator functions
- which DS code constants those translators handle
- which
except ApiResultErrorsites call a translator - which paginated list surfaces wire
translate_error=...
This lets us answer a more useful question than "what codes exist upstream":
- which stable
dsctloperations already normalize upstream failures - which surfaces still leak raw
ApiResultError
For reviewed exceptions to the current governance rule, use:
python tools/check_error_translation_governance.pyThe current allowlist is intentionally small. New raw ApiResultError sites or
new paginated list surfaces without translate_error should be treated as
review items, not as silent defaults.
The same governance flow also reviews translated ApiResultError sites that
drop the exception chain, because that would discard error.source on the
final CLI error payload.
The same governance check also flags matrix branches that recognize a concrete
DS code but still intentionally leave the outcome as raw ApiResultError.
Those reviewed raw branches currently fall into two buckets:
- controller-level fallback codes for unexpected upstream failures
- generic operation-failed codes that do not carry a stable domain meaning such as not-found, conflict, invalid-state, or permission-denied
Use the matrix extractor when you need a code-level view of current handwritten translations:
python tools/extract_dsctl_error_translation_matrix.py --format summary
python tools/extract_dsctl_error_translation_matrix.py --format markdown --output build/dsctl-error-translation-matrix.mdThe matrix is derived from the actual translator/helper functions in
src/dsctl/services/. It is intentionally implementation-oriented:
- module and helper name
- DS code constants or numeric codes used in branch conditions
- returned or raised
dsctlexception constructors
This is the fastest way to review whether a concrete DS result code already has stable CLI semantics.
Before adding or changing dsctl error translation:
- identify the relevant upstream controller/service path
- confirm whether the failure is HTTP-only,
Result-wrapped, or string-only - translate only known, stable upstream failure patterns
- leave unknown failures as raw API/HTTP errors until understood