Skip to content

Commit 30450c9

Browse files
yarikopticclaude
andcommitted
Enhance API client error messages
Improve error messages in dandiapi.py to provide clearer guidance: - Explain mutually exclusive api_url/dandi_instance parameters - Add hint to verify Dandiset ID and check permissions - Reference 'dandi ls' command for listing assets - Include version context in "No asset at path" errors These improvements help users quickly troubleshoot API access issues. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent a3dd9f9 commit 30450c9

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

dandi/dandiapi.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,11 @@ def __init__(
435435
dandi_instance = get_instance(instance_name)
436436
api_url = dandi_instance.api
437437
elif dandi_instance is not None:
438-
raise ValueError("api_url and dandi_instance are mutually exclusive")
438+
raise ValueError(
439+
"api_url and dandi_instance are mutually exclusive. "
440+
"Use either 'api_url' to specify a custom API URL, "
441+
"or 'dandi_instance' to use a registered DANDI instance, but not both."
442+
)
439443
else:
440444
dandi_instance = get_instance(api_url)
441445
super().__init__(api_url)
@@ -562,7 +566,11 @@ def get_dandiset(
562566
self, self.get(f"/dandisets/{dandiset_id}/")
563567
)
564568
except HTTP404Error:
565-
raise NotFoundError(f"No such Dandiset: {dandiset_id!r}")
569+
raise NotFoundError(
570+
f"No such Dandiset: {dandiset_id!r}. "
571+
"Verify the Dandiset ID is correct and that you have access. "
572+
f"View available Dandisets at {self.dandi_instance.gui}."
573+
)
566574
if version_id is not None and version_id != d.version_id:
567575
if version_id == DRAFT:
568576
return d.for_version(d.draft_version)
@@ -732,7 +740,11 @@ def get_asset(self, asset_id: str) -> BaseRemoteAsset:
732740
try:
733741
info = self.get(f"/assets/{asset_id}/info/")
734742
except HTTP404Error:
735-
raise NotFoundError(f"No such asset: {asset_id!r}")
743+
raise NotFoundError(
744+
f"No such asset: {asset_id!r}. "
745+
"Verify the asset ID is correct. "
746+
"Use 'dandi ls' to list available assets."
747+
)
736748
metadata = info.pop("metadata", None)
737749
return BaseRemoteAsset.from_base_data(self, info, metadata)
738750

@@ -1306,7 +1318,11 @@ def get_asset_by_path(self, path: str) -> RemoteAsset:
13061318
a for a in self.get_assets_with_path_prefix(path) if a.path == path
13071319
)
13081320
except ValueError:
1309-
raise NotFoundError(f"No asset at path {path!r}")
1321+
raise NotFoundError(
1322+
f"No asset at path {path!r} in version {self.version_id}. "
1323+
"Verify the path is correct and the asset exists in this version. "
1324+
"Use 'dandi ls' to list available assets."
1325+
)
13101326
else:
13111327
return asset
13121328

0 commit comments

Comments
 (0)