Skip to content

Commit 4a41c68

Browse files
Error output cleanup
1 parent e6236df commit 4a41c68

File tree

4 files changed

+52
-29
lines changed

4 files changed

+52
-29
lines changed

detection_rules/devtools.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
from .docs import REPO_DOCS_DIR, IntegrationSecurityDocs, IntegrationSecurityDocsMDX
4141
from .ecs import download_endpoint_schemas, download_schemas
4242
from .endgame import EndgameSchemaManager
43-
from .esql_errors import EsqlKibanaBaseError, EsqlSchemaError, EsqlSyntaxError, EsqlTypeMismatchError
43+
from .esql_errors import (
44+
ESQL_EXCEPTION_TYPES,
45+
)
4446
from .eswrap import CollectEvents, add_range_to_dsl
4547
from .ghwrap import GithubClient, update_gist
4648
from .integrations import (
@@ -1446,16 +1448,13 @@ def esql_remote_validation(
14461448
validator = ESQLValidator(r.contents.data.query) # type: ignore[reportIncompatibleMethodOverride]
14471449
_ = validator.remote_validate_rule_contents(kibana_client, elastic_client, r.contents, verbosity)
14481450
break
1449-
except (
1450-
ValueError,
1451-
BadRequestError,
1452-
EsqlSchemaError,
1453-
EsqlSyntaxError,
1454-
EsqlTypeMismatchError,
1455-
EsqlKibanaBaseError,
1456-
) as e:
1457-
click.echo(f"FAILURE: {e}")
1458-
fail_list.append(f"{r.contents.data.rule_id} FAILURE: {type(e)}: {e}")
1451+
except (ValueError, BadRequestError, *ESQL_EXCEPTION_TYPES) as e: # type: ignore[reportUnknownMemberType]
1452+
e_type = type(e) # type: ignore[reportUnknownMemberType]
1453+
if e_type in ESQL_EXCEPTION_TYPES:
1454+
_ = e.show() # type: ignore[reportUnknownMemberType]
1455+
else:
1456+
click.echo(f"FAILURE: {e_type}: {e}") # type: ignore[reportUnknownMemberType]
1457+
fail_list.append(f"{r.contents.data.rule_id} FAILURE: {e_type}: {e}") # type: ignore[reportUnknownMemberType]
14591458
failed_count += 1
14601459
break
14611460
except ESConnectionError as e:

detection_rules/esql_errors.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
"""ESQL exceptions."""
77

8+
from collections.abc import Sequence
9+
810
from elasticsearch import Elasticsearch # type: ignore[reportMissingTypeStubs]
911

10-
from .misc import getdefault
12+
from .misc import ClientError, getdefault
1113

1214
__all__ = (
1315
"EsqlKibanaBaseError",
@@ -21,7 +23,7 @@
2123

2224

2325
def cleanup_empty_indices(
24-
elastic_client: Elasticsearch, index_patterns: tuple[str, ...] = ("rule-test-*", "test-*")
26+
elastic_client: Elasticsearch, index_patterns: Sequence[str] = ("rule-test-*", "test-*")
2527
) -> None:
2628
"""Delete empty indices matching the given patterns."""
2729
if getdefault("skip_empty_index_cleanup")():
@@ -33,12 +35,16 @@ def cleanup_empty_indices(
3335
_ = elastic_client.indices.delete(index=empty_index)
3436

3537

36-
class EsqlKibanaBaseError(Exception):
38+
class EsqlKibanaBaseError(ClientError):
3739
"""Base class for ESQL exceptions with cleanup logic."""
3840

39-
def __init__(self, message: str, elastic_client: Elasticsearch) -> None:
41+
def __init__(
42+
self,
43+
message: str,
44+
elastic_client: Elasticsearch,
45+
) -> None:
4046
cleanup_empty_indices(elastic_client)
41-
super().__init__(message)
47+
super().__init__(message, original_error=self)
4248

4349

4450
class EsqlSchemaError(EsqlKibanaBaseError):
@@ -53,24 +59,39 @@ class EsqlSyntaxError(EsqlKibanaBaseError):
5359
"""Error with ESQL syntax."""
5460

5561

56-
class EsqlTypeMismatchError(Exception):
62+
class EsqlTypeMismatchError(ClientError):
5763
"""Error when validating types in ESQL. Can occur in stack or local schema comparison."""
5864

59-
def __init__(self, message: str, elastic_client: Elasticsearch | None = None) -> None:
65+
def __init__(
66+
self,
67+
message: str,
68+
elastic_client: Elasticsearch | None = None,
69+
) -> None:
6070
if elastic_client:
6171
cleanup_empty_indices(elastic_client)
62-
super().__init__(message)
72+
super().__init__(message, original_error=self)
6373

6474

65-
class EsqlSemanticError(Exception):
75+
class EsqlSemanticError(ClientError):
6676
"""Error with ESQL semantics. Validated through regex enforcement."""
6777

6878
def __init__(self, message: str) -> None:
69-
super().__init__(message)
79+
super().__init__(message, original_error=self)
7080

7181

72-
class EsqlUnknownIndexError(Exception):
82+
class EsqlUnknownIndexError(ClientError):
7383
"""Error with ESQL Indices. Validated through regex enforcement."""
7484

7585
def __init__(self, message: str) -> None:
76-
super().__init__(message)
86+
super().__init__(message, original_error=self)
87+
88+
89+
ESQL_EXCEPTION_TYPES = (
90+
EsqlSchemaError,
91+
EsqlSyntaxError,
92+
EsqlUnsupportedTypeError,
93+
EsqlTypeMismatchError,
94+
EsqlKibanaBaseError,
95+
EsqlSemanticError,
96+
EsqlUnknownIndexError,
97+
)

detection_rules/index_mappings.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,14 @@ def execute_query_against_indices(
347347
except BadRequestError as e:
348348
error_msg = str(e)
349349
if "parsing_exception" in error_msg:
350-
raise EsqlSyntaxError(str(e), elastic_client) from e
350+
raise EsqlSyntaxError(str(e), elastic_client) from None
351351
if "Unknown column" in error_msg:
352-
raise EsqlSchemaError(str(e), elastic_client) from e
352+
raise EsqlSchemaError(str(e), elastic_client) from None
353353
if "verification_exception" in error_msg and "unsupported type" in error_msg:
354-
raise EsqlUnsupportedTypeError(str(e), elastic_client) from e
354+
raise EsqlUnsupportedTypeError(str(e), elastic_client) from None
355355
if "verification_exception" in error_msg:
356-
raise EsqlTypeMismatchError(str(e), elastic_client) from e
357-
raise EsqlKibanaBaseError(str(e), elastic_client) from e
356+
raise EsqlTypeMismatchError(str(e), elastic_client) from None
357+
raise EsqlKibanaBaseError(str(e), elastic_client) from None
358358
if delete_indices or not misc.getdefault("skip_empty_index_cleanup")():
359359
for index_str in test_index_str.split(","):
360360
response = elastic_client.indices.delete(index=index_str.strip())

detection_rules/misc.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ def __init__(self, message: str, original_error: Exception | None = None) -> Non
4848

4949
def show(self, file: IO[Any] | None = None, err: bool = True) -> None:
5050
"""Print the error to the console."""
51-
msg = f"{click.style(f'CLI Error ({self.original_error_type})', fg='red', bold=True)}: {self.format_message()}"
51+
header = f"CLI Error ({self.original_error_type})"
52+
if "Esql" in str(self.original_error_type):
53+
header = f"{self.original_error_type}"
54+
msg = f"{click.style(header, fg='red', bold=True)}: {self.format_message()}"
5255
click.echo(msg, err=err, file=file)
5356

5457

0 commit comments

Comments
 (0)