mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add error handling for unsupported label uploading to frigate+ (#9775)
This commit is contained in:
parent
91cdf64602
commit
86341c3172
@ -275,6 +275,13 @@ def send_to_plus(id):
|
|||||||
box,
|
box,
|
||||||
event.label,
|
event.label,
|
||||||
)
|
)
|
||||||
|
except ValueError:
|
||||||
|
message = "Error uploading annotation, unsupported label provided."
|
||||||
|
logger.error(message)
|
||||||
|
return make_response(
|
||||||
|
jsonify({"success": False, "message": message}),
|
||||||
|
400,
|
||||||
|
)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.exception(ex)
|
logger.exception(ex)
|
||||||
return make_response(
|
return make_response(
|
||||||
@ -346,6 +353,13 @@ def false_positive(id):
|
|||||||
event.model_type,
|
event.model_type,
|
||||||
event.detector_type,
|
event.detector_type,
|
||||||
)
|
)
|
||||||
|
except ValueError:
|
||||||
|
message = "Error uploading false positive, unsupported label provided."
|
||||||
|
logger.error(message)
|
||||||
|
return make_response(
|
||||||
|
jsonify({"success": False, "message": message}),
|
||||||
|
400,
|
||||||
|
)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.exception(ex)
|
logger.exception(ex)
|
||||||
return make_response(
|
return make_response(
|
||||||
|
@ -171,6 +171,17 @@ class PlusApi:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not r.ok:
|
if not r.ok:
|
||||||
|
try:
|
||||||
|
error_response = r.json()
|
||||||
|
errors = error_response.get("errors", [])
|
||||||
|
for error in errors:
|
||||||
|
if (
|
||||||
|
error.get("param") == "label"
|
||||||
|
and error.get("type") == "invalid_enum_value"
|
||||||
|
):
|
||||||
|
raise ValueError(f"Unsupported label value provided: {label}")
|
||||||
|
except ValueError as e:
|
||||||
|
raise e
|
||||||
raise Exception(r.text)
|
raise Exception(r.text)
|
||||||
|
|
||||||
def add_annotation(
|
def add_annotation(
|
||||||
@ -193,6 +204,17 @@ class PlusApi:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not r.ok:
|
if not r.ok:
|
||||||
|
try:
|
||||||
|
error_response = r.json()
|
||||||
|
errors = error_response.get("errors", [])
|
||||||
|
for error in errors:
|
||||||
|
if (
|
||||||
|
error.get("param") == "label"
|
||||||
|
and error.get("type") == "invalid_enum_value"
|
||||||
|
):
|
||||||
|
raise ValueError(f"Unsupported label value provided: {label}")
|
||||||
|
except ValueError as e:
|
||||||
|
raise e
|
||||||
raise Exception(r.text)
|
raise Exception(r.text)
|
||||||
|
|
||||||
def get_model_download_url(
|
def get_model_download_url(
|
||||||
|
@ -7,7 +7,7 @@ import Link from '../components/Link';
|
|||||||
import { useApiHost } from '../api';
|
import { useApiHost } from '../api';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import useSWRInfinite from 'swr/infinite';
|
import useSWRInfinite from 'swr/infinite';
|
||||||
import axios from 'axios';
|
import axios, { AxiosError } from 'axios';
|
||||||
import { useState, useRef, useCallback, useMemo } from 'preact/hooks';
|
import { useState, useRef, useCallback, useMemo } from 'preact/hooks';
|
||||||
import VideoPlayer from '../components/VideoPlayer';
|
import VideoPlayer from '../components/VideoPlayer';
|
||||||
import { StarRecording } from '../icons/StarRecording';
|
import { StarRecording } from '../icons/StarRecording';
|
||||||
@ -79,6 +79,7 @@ export default function Events({ path, ...props }) {
|
|||||||
validBox: null,
|
validBox: null,
|
||||||
});
|
});
|
||||||
const [uploading, setUploading] = useState([]);
|
const [uploading, setUploading] = useState([]);
|
||||||
|
const [uploadErrors, setUploadErrors] = useState([]);
|
||||||
const [viewEvent, setViewEvent] = useState(props.event);
|
const [viewEvent, setViewEvent] = useState(props.event);
|
||||||
const [eventOverlay, setEventOverlay] = useState();
|
const [eventOverlay, setEventOverlay] = useState();
|
||||||
const [eventDetailType, setEventDetailType] = useState('clip');
|
const [eventDetailType, setEventDetailType] = useState('clip');
|
||||||
@ -328,27 +329,40 @@ export default function Events({ path, ...props }) {
|
|||||||
|
|
||||||
setUploading((prev) => [...prev, id]);
|
setUploading((prev) => [...prev, id]);
|
||||||
|
|
||||||
const response = false_positive
|
try {
|
||||||
? await axios.put(`events/${id}/false_positive`)
|
const response = false_positive
|
||||||
: await axios.post(`events/${id}/plus`, validBox ? { include_annotation: 1 } : {});
|
? await axios.put(`events/${id}/false_positive`)
|
||||||
|
: await axios.post(`events/${id}/plus`, validBox ? { include_annotation: 1 } : {});
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
mutate(
|
mutate(
|
||||||
(pages) =>
|
(pages) =>
|
||||||
pages.map((page) =>
|
pages.map((page) =>
|
||||||
page.map((event) => {
|
page.map((event) => {
|
||||||
if (event.id === id) {
|
if (event.id === id) {
|
||||||
return { ...event, plus_id: response.data.plus_id };
|
return { ...event, plus_id: response.data.plus_id };
|
||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (
|
||||||
|
e instanceof AxiosError &&
|
||||||
|
(e.response.data.message === 'Error uploading annotation, unsupported label provided.' ||
|
||||||
|
e.response.data.message === 'Error uploading false positive, unsupported label provided.')
|
||||||
|
) {
|
||||||
|
setUploadErrors((prev) => [...prev, { id, isUnsupported: true }]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setUploadErrors((prev) => [...prev, { id }]);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
setUploading((prev) => prev.filter((i) => i !== id));
|
||||||
}
|
}
|
||||||
|
|
||||||
setUploading((prev) => prev.filter((i) => i !== id));
|
|
||||||
|
|
||||||
if (state.showDownloadMenu && downloadEvent.id === id) {
|
if (state.showDownloadMenu && downloadEvent.id === id) {
|
||||||
setState({ ...state, showDownloadMenu: false });
|
setState({ ...state, showDownloadMenu: false });
|
||||||
}
|
}
|
||||||
@ -681,6 +695,7 @@ export default function Events({ path, ...props }) {
|
|||||||
viewEvent={viewEvent}
|
viewEvent={viewEvent}
|
||||||
setViewEvent={setViewEvent}
|
setViewEvent={setViewEvent}
|
||||||
uploading={uploading}
|
uploading={uploading}
|
||||||
|
uploadErrors={uploadErrors}
|
||||||
handleEventDetailTabChange={handleEventDetailTabChange}
|
handleEventDetailTabChange={handleEventDetailTabChange}
|
||||||
onEventFrameSelected={onEventFrameSelected}
|
onEventFrameSelected={onEventFrameSelected}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
@ -721,6 +736,7 @@ export default function Events({ path, ...props }) {
|
|||||||
lastEvent={lastEvent}
|
lastEvent={lastEvent}
|
||||||
lastEventRef={lastEventRef}
|
lastEventRef={lastEventRef}
|
||||||
uploading={uploading}
|
uploading={uploading}
|
||||||
|
uploadErrors={uploadErrors}
|
||||||
handleEventDetailTabChange={handleEventDetailTabChange}
|
handleEventDetailTabChange={handleEventDetailTabChange}
|
||||||
onEventFrameSelected={onEventFrameSelected}
|
onEventFrameSelected={onEventFrameSelected}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
@ -760,6 +776,7 @@ function Event({
|
|||||||
lastEvent,
|
lastEvent,
|
||||||
lastEventRef,
|
lastEventRef,
|
||||||
uploading,
|
uploading,
|
||||||
|
uploadErrors,
|
||||||
handleEventDetailTabChange,
|
handleEventDetailTabChange,
|
||||||
onEventFrameSelected,
|
onEventFrameSelected,
|
||||||
onDelete,
|
onDelete,
|
||||||
@ -769,6 +786,19 @@ function Event({
|
|||||||
onSave,
|
onSave,
|
||||||
showSubmitToPlus,
|
showSubmitToPlus,
|
||||||
}) {
|
}) {
|
||||||
|
const getUploadButtonState = (eventId) => {
|
||||||
|
const isUploading = uploading.includes(eventId);
|
||||||
|
const hasUploadError = uploadErrors.find((event) => event.id === eventId);
|
||||||
|
if (hasUploadError) {
|
||||||
|
if (hasUploadError.isUnsupported) {
|
||||||
|
return { isDisabled: true, label: 'Unsupported label' };
|
||||||
|
}
|
||||||
|
return { isDisabled: isUploading, label: 'Upload error' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = isUploading ? 'Uploading...' : 'Send to Frigate+';
|
||||||
|
return { isDisabled: isUploading, label };
|
||||||
|
};
|
||||||
const apiHost = useApiHost();
|
const apiHost = useApiHost();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -849,10 +879,10 @@ function Event({
|
|||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
color="gray"
|
color="gray"
|
||||||
disabled={uploading.includes(event.id)}
|
disabled={getUploadButtonState(event.id).isDisabled}
|
||||||
onClick={(e) => showSubmitToPlus(event.id, event.label, event?.data?.box || event.box, e)}
|
onClick={(e) => showSubmitToPlus(event.id, event.label, event?.data?.box || event.box, e)}
|
||||||
>
|
>
|
||||||
{uploading.includes(event.id) ? 'Uploading...' : 'Send to Frigate+'}
|
{getUploadButtonState(event.id).label}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
Loading…
Reference in New Issue
Block a user