diff --git a/hyperglass/exceptions/_common.py b/hyperglass/exceptions/_common.py
index 69bb9fc..9963324 100644
--- a/hyperglass/exceptions/_common.py
+++ b/hyperglass/exceptions/_common.py
@@ -2,7 +2,7 @@
# Standard Library
import json as _json
-from typing import Any, Dict, List, Union, Literal, Optional
+from typing import Any, Dict, List, Union, Literal, Optional, Set
# Third Party
from pydantic import ValidationError
@@ -48,7 +48,7 @@ class HyperglassError(Exception):
return {
"message": self._message,
"level": self._level,
- "keywords": self._keywords,
+ "keywords": self.keywords,
}
def json(self) -> str:
@@ -76,6 +76,18 @@ class HyperglassError(Exception):
return "\n".join(errs)
+ def _process_keywords(self) -> None:
+ out: Set[str] = set()
+ for val in self._keywords:
+ if isinstance(val, str):
+ out.add(val)
+ elif isinstance(val, list):
+ for v in val:
+ out.add(v)
+ else:
+ out.add(str(val))
+ self._keywords = list(out)
+
@property
def message(self) -> str:
"""Return the instance's `message` attribute."""
@@ -89,6 +101,7 @@ class HyperglassError(Exception):
@property
def keywords(self) -> List[str]:
"""Return the instance's `keywords` attribute."""
+ self._process_keywords()
return self._keywords
@property
diff --git a/hyperglass/ui/components/results/header.tsx b/hyperglass/ui/components/results/header.tsx
index 0adf3ea..f82a62a 100644
--- a/hyperglass/ui/components/results/header.tsx
+++ b/hyperglass/ui/components/results/header.tsx
@@ -1,5 +1,5 @@
+import { AccordionIcon, Box, HStack, Spinner, Text, Tooltip } from '@chakra-ui/react';
import { useMemo } from 'react';
-import { AccordionIcon, Box, Spinner, HStack, Text, Tooltip } from '@chakra-ui/react';
import { useConfig } from '~/context';
import { DynamicIcon } from '~/elements';
import { useColorValue, useOpposingColor, useStrf } from '~/hooks';
@@ -52,7 +52,7 @@ export const ResultHeader = (props: ResultHeaderProps): JSX.Element => {
) : (
= (
const addResponse = useFormState(s => s.addResponse);
const form = useFormState(s => s.form);
+ const [errorLevel, _setErrorLevel] = useState('error');
- const { data, error, isError, isLoading, refetch, isFetchedAfterMount } = useLGQuery(
- {
- queryLocation,
- queryTarget: form.queryTarget,
- queryType: form.queryType,
- },
+ const setErrorLevel = (level: ResponseLevel): void => {
+ let e: ErrorLevels = 'error';
+ switch (level) {
+ case 'success':
+ e = level;
+ break;
+ case 'warning' || 'error':
+ e = 'warning';
+ break;
+ }
+ _setErrorLevel(e);
+ };
+
+ const { data, error, isLoading, refetch, isFetchedAfterMount } = useLGQuery(
+ { queryLocation, queryTarget: form.queryTarget, queryType: form.queryType },
{
onSuccess(data) {
if (device !== null) {
addResponse(device.id, data);
}
+ if (isLGOutputOrError(data)) {
+ console.error(data);
+ setErrorLevel(data.level);
+ }
},
onError(error) {
- console.error(error);
+ console.error({ error });
+ if (isLGOutputOrError(error)) {
+ setErrorLevel(error.level);
+ }
},
},
);
+
+ const isError = useMemo(() => isLGOutputOrError(data), [data, error]);
+
const isCached = useMemo(() => data?.cached || !isFetchedAfterMount, [data, isFetchedAfterMount]);
const strF = useStrf();
@@ -123,23 +143,6 @@ const _Result: React.ForwardRefRenderFunction = (
return messages.general;
}, [error, data, messages.general, messages.requestTimeout]);
- const errorLevel = useMemo(() => {
- const statusMap = {
- success: 'success',
- warning: 'warning',
- error: 'warning',
- danger: 'error',
- } as { [K in ResponseLevel]: 'success' | 'warning' | 'error' };
-
- let e: ErrorLevels = 'error';
-
- if (isLGError(error)) {
- const idx = error.level as ResponseLevel;
- e = statusMap[idx];
- }
- return e;
- }, [error]);
-
const tableComponent = useMemo(() => {
let result = false;
if (data?.format === 'application/json') {