Skip to content

Commit 8bb2ac8

Browse files
committed
Improve error message for object validate
1 parent 13972a2 commit 8bb2ac8

File tree

5 files changed

+206
-54
lines changed

5 files changed

+206
-54
lines changed

infrahub_sdk/ctl/menu.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from ..async_typer import AsyncTyper
88
from ..ctl.client import initialize_client
99
from ..ctl.utils import catch_exception, init_logging
10+
from ..exceptions import ObjectValidationError
1011
from ..spec.menu import MenuFile
1112
from .parameters import CONFIG_PARAM
1213
from .utils import load_yamlfile_from_disk_and_exit
@@ -44,11 +45,16 @@ async def load(
4445
schema = await client.schema.get(kind=file.spec.kind, branch=branch)
4546

4647
for idx, item in enumerate(file.spec.data):
47-
await file.spec.create_node(
48-
client=client,
49-
schema=schema,
50-
data=item,
51-
branch=branch,
52-
default_schema_kind=file.spec.kind,
53-
context={"list_index": idx},
54-
)
48+
try:
49+
await file.spec.create_node(
50+
client=client,
51+
schema=schema,
52+
position=[idx + 1],
53+
data=item,
54+
branch=branch,
55+
default_schema_kind=file.spec.kind,
56+
context={"list_index": idx},
57+
)
58+
except ObjectValidationError as exc:
59+
console.print(f"[red] {exc!s}")
60+
raise typer.Exit(1)

infrahub_sdk/ctl/object.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
from ..async_typer import AsyncTyper
88
from ..ctl.client import initialize_client
99
from ..ctl.utils import catch_exception, init_logging
10-
from ..exceptions import ValidationError
10+
from ..exceptions import ObjectValidationError, ValidationError
1111
from ..spec.object import ObjectFile
1212
from .parameters import CONFIG_PARAM
13-
from .utils import load_yamlfile_from_disk_and_exit
13+
from .utils import (
14+
display_object_validate_format_error,
15+
display_object_validate_format_success,
16+
load_yamlfile_from_disk_and_exit,
17+
)
1418

1519
app = AsyncTyper()
1620
console = Console()
@@ -45,19 +49,22 @@ async def load(
4549
for file in files:
4650
try:
4751
await file.validate_format(client=client, branch=branch)
48-
except ValidationError as e:
52+
except ValidationError as exc:
4953
has_errors = True
50-
if file.multiple_documents:
51-
console.print(f"[red] File '{file.location}' [{file.document_position}] is not valid!")
52-
else:
53-
console.print(f"[red] File '{file.location}' is not valid!")
54-
console.print(f"[red] {e.message}")
54+
display_object_validate_format_error(file=file, error=exc, console=console)
5555

5656
if has_errors:
5757
raise typer.Exit(1)
5858

5959
for file in files:
60-
await file.process(client=client, branch=branch)
60+
try:
61+
await file.process(client=client, branch=branch)
62+
except ObjectValidationError as exc:
63+
has_errors = True
64+
console.print(f"[red] {exc!s}")
65+
66+
if has_errors:
67+
raise typer.Exit(1)
6168

6269

6370
@app.command()
@@ -81,17 +88,10 @@ async def validate(
8188
for file in files:
8289
try:
8390
await file.validate_format(client=client, branch=branch)
84-
if file.multiple_documents:
85-
console.print(f"[green] File '{file.location}' [{file.document_position}] is Valid!")
86-
else:
87-
console.print(f"[green] File '{file.location}' is Valid!")
88-
except ValidationError as e:
91+
display_object_validate_format_success(file=file, console=console)
92+
except ValidationError as exc:
8993
has_errors = True
90-
if file.multiple_documents:
91-
console.print(f"[red] File '{file.location}' [{file.document_position}] is not valid!")
92-
else:
93-
console.print(f"[red] File '{file.location}' is not valid!")
94-
console.print(f"[red] {e.message}")
94+
display_object_validate_format_error(file=file, error=exc, console=console)
9595

9696
if has_errors:
9797
raise typer.Exit(1)

infrahub_sdk/ctl/utils.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
SchemaNotFoundError,
2626
ServerNotReachableError,
2727
ServerNotResponsiveError,
28+
ValidationError,
2829
)
2930
from ..yaml import YamlFile
3031
from .client import initialize_client_sync
3132
from .exceptions import QueryNotFoundError
3233

3334
if TYPE_CHECKING:
3435
from ..schema.repository import InfrahubRepositoryConfig
36+
from ..spec.object import ObjectFile
3537

3638
YamlFileVar = TypeVar("YamlFileVar", bound=YamlFile)
3739
T = TypeVar("T")
@@ -199,3 +201,22 @@ def load_yamlfile_from_disk_and_exit(
199201
raise typer.Exit(1)
200202

201203
return data_files
204+
205+
206+
def display_object_validate_format_success(file: ObjectFile, console: Console) -> None:
207+
if file.multiple_documents:
208+
console.print(f"[green] File '{file.location}' [{file.document_position}] is Valid!")
209+
else:
210+
console.print(f"[green] File '{file.location}' is Valid!")
211+
212+
213+
def display_object_validate_format_error(file: ObjectFile, error: ValidationError, console: Console) -> None:
214+
if file.multiple_documents:
215+
console.print(f"[red] File '{file.location}' [{file.document_position}] is not valid!")
216+
else:
217+
console.print(f"[red] File '{file.location}' is not valid!")
218+
if error.messages:
219+
for message in error.messages:
220+
console.print(f"[red] {message}")
221+
else:
222+
console.print(f"[red] {error.message}")

infrahub_sdk/exceptions.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,25 @@ def __init__(self, name: str, message: str | None = None):
113113

114114

115115
class ValidationError(Error):
116-
def __init__(self, identifier: str, message: str):
116+
def __init__(self, identifier: str, message: str | None = None, messages: list[str] | None = None):
117117
self.identifier = identifier
118118
self.message = message
119+
self.messages = messages
120+
if not messages and not message:
121+
self.message = f"Validation Error for {self.identifier}"
119122
super().__init__(self.message)
120123

121124

125+
class ObjectValidationError(Error):
126+
def __init__(self, position: list[int | str], message: str):
127+
self.position = position
128+
self.message = message
129+
super().__init__(self.message)
130+
131+
def __str__(self) -> str:
132+
return f"{'.'.join(map(str, self.position))}: {self.message}"
133+
134+
122135
class AuthenticationError(Error):
123136
def __init__(self, message: str | None = None):
124137
self.message = message or "Authentication Error, unable to execute the query."

0 commit comments

Comments
 (0)