enable logs; add sentry logging to block runs (debugger) (#3205)
This commit is contained in:
@@ -5,30 +5,37 @@ import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { queryClient } from "./api/QueryClient";
|
||||
|
||||
import { PostHogProvider } from "posthog-js/react";
|
||||
import { LoggingContext, loggingStub } from "@/store/LoggingContext";
|
||||
import { UserContext } from "@/store/UserContext";
|
||||
|
||||
const postHogOptions = {
|
||||
api_host: "https://app.posthog.com",
|
||||
};
|
||||
|
||||
const getLogging = () => {
|
||||
return loggingStub;
|
||||
};
|
||||
|
||||
const getUser = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<UserContext.Provider value={getUser}>
|
||||
<PostHogProvider
|
||||
apiKey="phc_bVT2ugnZhMHRWqMvSRHPdeTjaPxQqT3QSsI3r5FlQR5"
|
||||
options={postHogOptions}
|
||||
>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider defaultTheme="dark">
|
||||
<RouterProvider router={router} />
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</PostHogProvider>
|
||||
</UserContext.Provider>
|
||||
<LoggingContext.Provider value={getLogging}>
|
||||
<UserContext.Provider value={getUser}>
|
||||
<PostHogProvider
|
||||
apiKey="phc_bVT2ugnZhMHRWqMvSRHPdeTjaPxQqT3QSsI3r5FlQR5"
|
||||
options={postHogOptions}
|
||||
>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider defaultTheme="dark">
|
||||
<RouterProvider router={router} />
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</PostHogProvider>
|
||||
</UserContext.Provider>
|
||||
</LoggingContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
9
skyvern-frontend/src/hooks/useLogging.ts
Normal file
9
skyvern-frontend/src/hooks/useLogging.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { LoggingContext } from "@/store/LoggingContext";
|
||||
import { useContext } from "react";
|
||||
|
||||
function useLogging() {
|
||||
const getLogging = useContext(LoggingContext);
|
||||
return getLogging();
|
||||
}
|
||||
|
||||
export { useLogging };
|
||||
@@ -6,13 +6,13 @@ function DebuggerRun() {
|
||||
|
||||
const workflowFailureReason = workflowRun?.failure_reason ? (
|
||||
<div
|
||||
className="align-self-start max-h-[8rem] w-full overflow-y-auto rounded-md border border-red-600 p-4"
|
||||
className="align-self-start h-[8rem] w-full overflow-y-auto rounded-md border border-red-600 p-4"
|
||||
style={{
|
||||
backgroundColor: "rgba(220, 38, 38, 0.10)",
|
||||
width: "calc(100% - 2rem)",
|
||||
}}
|
||||
>
|
||||
<div className="font-bold">Workflow Failure Reason</div>
|
||||
<div className="font-bold">Run Failure Reason</div>
|
||||
<div className="text-sm">{workflowRun.failure_reason}</div>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getClient } from "@/api/AxiosClient";
|
||||
import { ProxyLocation } from "@/api/types";
|
||||
import { Timer } from "@/components/Timer";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
import { useLogging } from "@/hooks/useLogging";
|
||||
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||
|
||||
import { useNodeLabelChangeHandler } from "@/routes/workflows/hooks/useLabelChangeHandler";
|
||||
@@ -131,6 +132,7 @@ function NodeHeader({
|
||||
totpUrl,
|
||||
type,
|
||||
}: Props) {
|
||||
const log = useLogging();
|
||||
const {
|
||||
blockLabel: urlBlockLabel,
|
||||
workflowPermanentId,
|
||||
@@ -214,7 +216,7 @@ function NodeHeader({
|
||||
await saveWorkflow.mutateAsync();
|
||||
|
||||
if (!workflowPermanentId) {
|
||||
console.error("There is no workflowPermanentId");
|
||||
log.error("Run block: there is no workflowPermanentId");
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to start workflow block run",
|
||||
@@ -224,7 +226,7 @@ function NodeHeader({
|
||||
}
|
||||
|
||||
if (!debugSession) {
|
||||
console.error("There is no debug session, yet");
|
||||
log.error("Run block: there is no debug session, yet");
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to start workflow block run",
|
||||
@@ -263,6 +265,12 @@ function NodeHeader({
|
||||
});
|
||||
|
||||
if (!body) {
|
||||
log.error("Run block: could not construct run payload", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession.debug_session_id,
|
||||
browserSessionId: debugSession.browser_session_id,
|
||||
});
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to start workflow block run",
|
||||
@@ -271,6 +279,13 @@ function NodeHeader({
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Run block: sending run payload", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession.debug_session_id,
|
||||
browserSessionId: debugSession.browser_session_id,
|
||||
});
|
||||
|
||||
return await client.post<Payload, { data: { run_id: string } }>(
|
||||
"/run/workflows/blocks",
|
||||
body,
|
||||
@@ -278,7 +293,12 @@ function NodeHeader({
|
||||
},
|
||||
onSuccess: (response) => {
|
||||
if (!response) {
|
||||
console.error("No response");
|
||||
log.error("Run block: no response", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession?.debug_session_id,
|
||||
browserSessionId: debugSession?.browser_session_id,
|
||||
});
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to start workflow block run",
|
||||
@@ -287,6 +307,14 @@ function NodeHeader({
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Run block: run started", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession?.debug_session_id,
|
||||
browserSessionId: debugSession?.browser_session_id,
|
||||
runId: response.data.run_id,
|
||||
});
|
||||
|
||||
toast({
|
||||
variant: "success",
|
||||
title: "Workflow block run started",
|
||||
@@ -299,6 +327,13 @@ function NodeHeader({
|
||||
},
|
||||
onError: (error: AxiosError) => {
|
||||
const detail = (error.response?.data as { detail?: string })?.detail;
|
||||
log.error("Run block: error", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession?.debug_session_id,
|
||||
browserSessionId: debugSession?.browser_session_id,
|
||||
error,
|
||||
});
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to start workflow block run",
|
||||
@@ -310,7 +345,10 @@ function NodeHeader({
|
||||
const cancelBlock = useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!debugSession) {
|
||||
console.error("Missing debug session");
|
||||
log.error("Cancel block: missing debug session", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
});
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to cancel workflow block run",
|
||||
@@ -326,6 +364,12 @@ function NodeHeader({
|
||||
.then((response) => response.data);
|
||||
},
|
||||
onSuccess: () => {
|
||||
log.info("Cancel block: canceled", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession?.debug_session_id,
|
||||
browserSessionId: debugSession?.browser_session_id,
|
||||
});
|
||||
toast({
|
||||
variant: "success",
|
||||
title: "Workflow Canceled",
|
||||
@@ -333,6 +377,13 @@ function NodeHeader({
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
log.error("Cancel block: error", {
|
||||
workflowPermanentId,
|
||||
blockLabel,
|
||||
debugSessionId: debugSession?.debug_session_id,
|
||||
browserSessionId: debugSession?.browser_session_id,
|
||||
error,
|
||||
});
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error",
|
||||
|
||||
26
skyvern-frontend/src/store/LoggingContext.ts
Normal file
26
skyvern-frontend/src/store/LoggingContext.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
type LogFn = (message: string, data?: Record<string, unknown>) => void;
|
||||
|
||||
interface Logging {
|
||||
info: LogFn;
|
||||
warn: LogFn;
|
||||
error: LogFn;
|
||||
}
|
||||
|
||||
// make this a stub of LogFn that does nothing
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const noop: LogFn = (..._: Parameters<LogFn>) => {};
|
||||
|
||||
const stub: Logging = {
|
||||
info: noop,
|
||||
warn: noop,
|
||||
error: noop,
|
||||
};
|
||||
|
||||
type GetLogging = () => Logging;
|
||||
|
||||
const LoggingContext = createContext<GetLogging>(() => stub);
|
||||
|
||||
export { LoggingContext, stub as loggingStub };
|
||||
Reference in New Issue
Block a user