Skip to content

Commit adb149e

Browse files
authored
Fix telemetry "Unknown" errors: wrap string exceptions, add missing instrumentation, and catch-all decorato (#53)
* adding telemetry updates to update unknown * Fix telemetry reporting: wrap string exceptions in Exception() and add catch-all decorator - Replace all exception='string' calls with exception=Exception('string') across custom.py, _utils.py, and _precheckutils.py so that ExceptionName in telemetry shows 'Exception' instead of 'str' - Add _telemetry_catch_all decorator to top-level command functions (create, delete, update, upgrade) to catch unhandled exceptions, log them to telemetry with proper ExceptionName/FaultType, and re-raise as CLIInternalError instead of letting them become 'UnknownError' * Fix mypy and ruff: add type annotations to _telemetry_catch_all decorator and fix import sorting * Apply ruff format to fix CI format check * Remove accidentally committed files
1 parent c6096ea commit adb149e

4 files changed

Lines changed: 202 additions & 61 deletions

File tree

src/connectedk8s/azext_connectedk8s/_constants.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@
148148
Agent_State_Succeeded = "Succeeded"
149149
Agent_State_Failed = "Failed"
150150
Agent_State_Timeout = 15
151+
Agent_State_Timeout_Fault_Type = "agent-state-timeout-error"
152+
Provisioned_Cluster_Operation_Fault_Type = "provisioned-cluster-unsupported-operation"
153+
Update_No_Params_Fault_Type = "update-no-parameters-specified"
154+
Update_Proxy_Conflict_Fault_Type = "update-proxy-parameters-conflict"
155+
Connected_Cluster_Resource_Id_None_Fault_Type = (
156+
"connected-cluster-resource-id-none-error"
157+
)
158+
Custom_Locations_Enable_Failed_Fault_Type = "custom-locations-enable-failed"
151159
Get_Credentials_Failed_Fault_Type = "failed-to-get-list-cluster-user-credentials"
152160
Failed_To_Merge_Credentials_Fault_Type = "failed-to-merge-credentials"
153161
Kubeconfig_Failed_To_Load_Fault_Type = "failed-to-load-kubeconfig-file"

src/connectedk8s/azext_connectedk8s/_precheckutils.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def executing_cluster_diagnostic_checks_job(
206206
'cluster-diagnostic-checks -n azure-arc-release" and try onboarding again'
207207
)
208208
telemetry.set_exception(
209-
exception=error_kubectl_delete_helm.decode("ascii"),
209+
exception=Exception(error_kubectl_delete_helm.decode("ascii")),
210210
fault_type=consts.Cluster_Diagnostic_Checks_Release_Cleanup_Failed,
211211
summary="Error while executing Cluster Diagnostic Checks Job",
212212
)
@@ -309,7 +309,9 @@ def executing_cluster_diagnostic_checks_job(
309309
# If job is not scheduled then we will delete the helm release
310310
if is_job_scheduled is False:
311311
telemetry.set_exception(
312-
exception="Couldn't schedule Cluster Diagnostic Checks Job in the cluster",
312+
exception=Exception(
313+
"Couldn't schedule Cluster Diagnostic Checks Job in the cluster"
314+
),
313315
fault_type=consts.Cluster_Diagnostic_Checks_Job_Not_Scheduled,
314316
summary="Couldn't schedule Cluster Diagnostic Checks Job in the cluster",
315317
)
@@ -390,7 +392,9 @@ def executing_cluster_diagnostic_checks_job(
390392
)
391393

392394
telemetry.set_exception(
393-
exception="Couldn't complete Cluster Diagnostic Checks Job after scheduling in the cluster",
395+
exception=Exception(
396+
"Couldn't complete Cluster Diagnostic Checks Job after scheduling in the cluster"
397+
),
394398
fault_type=consts.Cluster_Diagnostic_Checks_Job_Not_Complete,
395399
summary="Couldn't complete Cluster Diagnostic Checks Job after scheduling in the cluster",
396400
)
@@ -467,7 +471,7 @@ def helm_install_release_cluster_diagnostic_checks(
467471
telemetry.set_user_fault()
468472

469473
telemetry.set_exception(
470-
exception=error,
474+
exception=Exception(error),
471475
fault_type=consts.Cluster_Diagnostic_Checks_Helm_Install_Failed_Fault_Type,
472476
summary="Unable to install cluster diagnostic checks helm release",
473477
)

src/connectedk8s/azext_connectedk8s/_utils.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def validate_connect_rp_location(cmd: CLICommand, location: str) -> None:
127127
]
128128
if location.lower() not in rp_locations:
129129
telemetry.set_exception(
130-
exception="Location not supported",
130+
exception=Exception("Location not supported"),
131131
fault_type=consts.Invalid_Location_Fault_Type,
132132
summary="Provided location is not supported for creating connected clusters",
133133
)
@@ -146,7 +146,9 @@ def validate_custom_token(
146146
if os.getenv("AZURE_ACCESS_TOKEN"):
147147
if os.getenv("AZURE_SUBSCRIPTION_ID") is None:
148148
telemetry.set_exception(
149-
exception="Required environment variable SubscriptionId not set, for custom Azure access token",
149+
exception=Exception(
150+
"Required environment variable SubscriptionId not set, for custom Azure access token"
151+
),
150152
fault_type=consts.Custom_Access_Token_Env_Var_Sub_Id_Missing_Fault_Type,
151153
summary="Required environment variable SubscriptionId not set, for custom Azure access token",
152154
)
@@ -155,7 +157,9 @@ def validate_custom_token(
155157
)
156158
if os.getenv("AZURE_TENANT_ID") is None:
157159
telemetry.set_exception(
158-
exception="Required environment variable TenantId not set, for custom Azure access token",
160+
exception=Exception(
161+
"Required environment variable TenantId not set, for custom Azure access token"
162+
),
159163
fault_type=consts.Custom_Access_Token_Env_Var_Tenant_Id_Missing_Fault_Type,
160164
summary="Required environment variable TenantId not set, for custom Azure access token",
161165
)
@@ -248,7 +252,7 @@ def pull_helm_chart(
248252
):
249253
error_summary = "This CLI version does not support upgrading to Agents versions older than v1.14"
250254
telemetry.set_exception(
251-
exception="Operation not supported on older Agents",
255+
exception=Exception("Operation not supported on older Agents"),
252256
fault_type=consts.Operation_Not_Supported_Fault_Type,
253257
summary=error_summary,
254258
)
@@ -289,7 +293,7 @@ def pull_helm_chart(
289293
error = error_helm_chart_pull.decode("ascii")
290294
if i == retry_count - 1:
291295
telemetry.set_exception(
292-
exception=error,
296+
exception=Exception(error),
293297
fault_type=consts.Pull_HelmChart_Fault_Type,
294298
summary=f"Unable to pull {chart_name} helm charts from the registry",
295299
)
@@ -347,7 +351,7 @@ def save_cluster_diagnostic_checks_pod_description(
347351
f.write(pod_description)
348352
else:
349353
telemetry.set_exception(
350-
exception=error_describe_job_pod.decode("ascii"),
354+
exception=Exception(error_describe_job_pod.decode("ascii")),
351355
fault_type=consts.Cluster_Diagnostic_Checks_Pod_Description_Save_Failed,
352356
summary="Failed to save cluster diagnostic checks pod description in the local machine",
353357
)
@@ -415,7 +419,7 @@ def check_cluster_DNS(
415419
+ "\nWe found an issue with the DNS resolution on your cluster."
416420
)
417421
telemetry.set_exception(
418-
exception="DNS resolution check failed in the cluster",
422+
exception=Exception("DNS resolution check failed in the cluster"),
419423
fault_type=consts.DNS_Check_Failed,
420424
summary="DNS check failed in the cluster",
421425
)
@@ -526,7 +530,9 @@ def check_cluster_outbound_connectivity(
526530
)
527531
telemetry.set_user_fault()
528532
telemetry.set_exception(
529-
exception="Outbound network connectivity check failed for the Cluster Connect endpoint",
533+
exception=Exception(
534+
"Outbound network connectivity check failed for the Cluster Connect endpoint"
535+
),
530536
fault_type=consts.Outbound_Connectivity_Check_Failed_For_Cluster_Connect,
531537
summary="Outbound network connectivity check failed for the Cluster Connect precheck endpoint",
532538
)
@@ -595,7 +601,9 @@ def check_cluster_outbound_connectivity(
595601
"required for onboarding."
596602
)
597603
telemetry.set_exception(
598-
exception="Outbound network connectivity check failed for onboarding",
604+
exception=Exception(
605+
"Outbound network connectivity check failed for onboarding"
606+
),
599607
fault_type=consts.Outbound_Connectivity_Check_Failed_For_Onboarding,
600608
summary="Outbound network connectivity check for onboarding failed in the cluster",
601609
)
@@ -646,7 +654,7 @@ def check_cluster_outbound_connectivity(
646654
+ "\nWe found an issue with Outbound network connectivity from the cluster."
647655
)
648656
telemetry.set_exception(
649-
exception="Outbound network connectivity check failed",
657+
exception=Exception("Outbound network connectivity check failed"),
650658
fault_type=consts.Outbound_Connectivity_Check_Failed,
651659
summary="Outbound network connectivity check failed in the cluster",
652660
)
@@ -769,7 +777,7 @@ def add_helm_repo(
769777
if response_helm_repo.returncode != 0:
770778
error = error_helm_repo.decode("ascii")
771779
telemetry.set_exception(
772-
exception=error,
780+
exception=Exception(error),
773781
fault_type=consts.Add_HelmRepo_Fault_Type,
774782
summary="Failed to add helm repository",
775783
)
@@ -820,7 +828,7 @@ def get_helm_registry(
820828
)
821829
else:
822830
telemetry.set_exception(
823-
exception="No content in response",
831+
exception=Exception("No content in response"),
824832
fault_type=consts.Get_HelmRegistery_Path_Fault_Type,
825833
summary="No content in acr path response",
826834
)
@@ -881,7 +889,7 @@ def get_helm_values(
881889
)
882890
else:
883891
telemetry.set_exception(
884-
exception="No content in response",
892+
exception=Exception("No content in response"),
885893
fault_type=consts.Get_HelmRegistery_Path_Fault_Type,
886894
summary="No content in acr path response",
887895
)
@@ -915,7 +923,7 @@ def health_check_dp(cmd: CLICommand, config_dp_endpoint: str) -> bool:
915923
return True
916924

917925
telemetry.set_exception(
918-
exception="Error while performing DP health check",
926+
exception=Exception("Error while performing DP health check"),
919927
fault_type=consts.DP_Health_Check_Fault_Type,
920928
summary="Error while performing DP health check",
921929
)
@@ -977,7 +985,7 @@ def update_gateway_cluster_link(
977985
return True
978986

979987
telemetry.set_exception(
980-
exception=f"Gateway {operation_type} failed",
988+
exception=Exception(f"Gateway {operation_type} failed"),
981989
fault_type=consts.GATEWAY_LINK_FAULT_TYPE,
982990
summary=f"Gateway {operation_type} failed",
983991
)
@@ -1230,7 +1238,7 @@ def delete_arc_agents(
12301238
):
12311239
telemetry.set_user_fault()
12321240
telemetry.set_exception(
1233-
exception=error_helm_delete.decode("ascii"),
1241+
exception=Exception(error_helm_delete.decode("ascii")),
12341242
fault_type=consts.Delete_HelmRelease_Fault_Type,
12351243
summary="Unable to delete helm release",
12361244
)
@@ -1434,7 +1442,7 @@ def helm_install_release(
14341442
):
14351443
telemetry.set_user_fault()
14361444
telemetry.set_exception(
1437-
exception=helm_install_error_message,
1445+
exception=Exception(helm_install_error_message),
14381446
fault_type=consts.Install_HelmRelease_Fault_Type,
14391447
summary="Unable to install helm release",
14401448
)
@@ -1548,7 +1556,7 @@ def get_release_namespace(
15481556
telemetry.set_user_fault()
15491557

15501558
telemetry.set_exception(
1551-
exception=error,
1559+
exception=Exception(error),
15521560
fault_type=consts.List_HelmRelease_Fault_Type,
15531561
summary="Unable to list helm release",
15541562
)
@@ -1634,7 +1642,9 @@ def check_provider_registrations(
16341642
).registration_state
16351643
if cc_registration_state not in consts.allowed_rp_registration_states:
16361644
telemetry.set_exception(
1637-
exception=f"{consts.Connected_Cluster_Provider_Namespace} provider is not registered",
1645+
exception=Exception(
1646+
f"{consts.Connected_Cluster_Provider_Namespace} provider is not registered"
1647+
),
16381648
fault_type=consts.CC_Provider_Namespace_Not_Registered_Fault_Type,
16391649
summary=f"{consts.Connected_Cluster_Provider_Namespace} provider is not registered",
16401650
)
@@ -1649,7 +1659,9 @@ def check_provider_registrations(
16491659
if kc_registration_state not in consts.allowed_rp_registration_states:
16501660
if is_workload_identity_enabled:
16511661
telemetry.set_exception(
1652-
exception=f"{consts.Kubernetes_Configuration_Provider_Namespace} provider is not registered",
1662+
exception=Exception(
1663+
f"{consts.Kubernetes_Configuration_Provider_Namespace} provider is not registered"
1664+
),
16531665
fault_type=consts.Kubernetes_Configuration_Provider_Namespace_Not_Registered_Fault_Type,
16541666
summary=f"{consts.Kubernetes_Configuration_Provider_Namespace} provider is not registered",
16551667
)
@@ -1670,7 +1682,9 @@ def check_provider_registrations(
16701682
).registration_state
16711683
if hc_registration_state not in consts.allowed_rp_registration_states:
16721684
telemetry.set_exception(
1673-
exception=f"{consts.Hybrid_Compute_Provider_Namespace} provider is not registered",
1685+
exception=Exception(
1686+
f"{consts.Hybrid_Compute_Provider_Namespace} provider is not registered"
1687+
),
16741688
fault_type=consts.HC_Provider_Namespace_Not_Registered_Fault_Type,
16751689
summary=f"{consts.Hybrid_Compute_Provider_Namespace} provider is not registered",
16761690
)
@@ -1829,7 +1843,7 @@ def helm_update_agent(
18291843
if "forbidden" in error or "timed out waiting for the condition" in error:
18301844
telemetry.set_user_fault()
18311845
telemetry.set_exception(
1832-
exception=error,
1846+
exception=Exception(error),
18331847
fault_type=consts.Get_Helm_Values_Failed,
18341848
summary="Error while doing helm get values azure-arc",
18351849
)
@@ -1866,7 +1880,7 @@ def helm_update_agent(
18661880
):
18671881
telemetry.set_user_fault()
18681882
telemetry.set_exception(
1869-
exception=helm_upgrade_error_message,
1883+
exception=Exception(helm_upgrade_error_message),
18701884
fault_type=consts.Install_HelmRelease_Fault_Type,
18711885
summary="Unable to install helm release",
18721886
)

0 commit comments

Comments
 (0)