enable logs; add sentry logging to block runs (debugger) (#3205)

This commit is contained in:
Jonathan Dobson
2025-08-15 11:25:53 -04:00
committed by GitHub
parent e09bf89f19
commit fc55729257
5 changed files with 111 additions and 18 deletions

View File

@@ -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>
);
}

View File

@@ -0,0 +1,9 @@
import { LoggingContext } from "@/store/LoggingContext";
import { useContext } from "react";
function useLogging() {
const getLogging = useContext(LoggingContext);
return getLogging();
}
export { useLogging };

View File

@@ -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;

View File

@@ -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",

View 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 };