mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
fix(logs): address PR review — redact workflowInput, improve fallback heuristic, add isPending guard
This commit is contained in:
@@ -266,6 +266,8 @@ interface LogDetailsProps {
|
||||
hasPrev?: boolean
|
||||
/** Callback to retry a failed execution */
|
||||
onRetryExecution?: () => void
|
||||
/** Whether a retry is currently in progress */
|
||||
isRetryPending?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,6 +285,7 @@ export const LogDetails = memo(function LogDetails({
|
||||
hasNext = false,
|
||||
hasPrev = false,
|
||||
onRetryExecution,
|
||||
isRetryPending = false,
|
||||
}: LogDetailsProps) {
|
||||
const [isExecutionSnapshotOpen, setIsExecutionSnapshotOpen] = useState(false)
|
||||
const scrollAreaRef = useRef<HTMLDivElement>(null)
|
||||
@@ -399,6 +402,7 @@ export const LogDetails = memo(function LogDetails({
|
||||
variant='ghost'
|
||||
className='!p-1'
|
||||
onClick={() => onRetryExecution?.()}
|
||||
disabled={isRetryPending}
|
||||
aria-label='Retry execution'
|
||||
>
|
||||
<Redo className='h-[14px] w-[14px]' />
|
||||
|
||||
@@ -24,6 +24,7 @@ interface LogRowContextMenuProps {
|
||||
onClearAllFilters: () => void
|
||||
onCancelExecution: () => void
|
||||
onRetryExecution: () => void
|
||||
isRetryPending?: boolean
|
||||
isFilteredByThisWorkflow: boolean
|
||||
hasActiveFilters: boolean
|
||||
}
|
||||
@@ -45,6 +46,7 @@ export const LogRowContextMenu = memo(function LogRowContextMenu({
|
||||
onClearAllFilters,
|
||||
onCancelExecution,
|
||||
onRetryExecution,
|
||||
isRetryPending = false,
|
||||
isFilteredByThisWorkflow,
|
||||
hasActiveFilters,
|
||||
}: LogRowContextMenuProps) {
|
||||
@@ -78,9 +80,9 @@ export const LogRowContextMenu = memo(function LogRowContextMenu({
|
||||
>
|
||||
{isRetryable && (
|
||||
<>
|
||||
<DropdownMenuItem onSelect={onRetryExecution}>
|
||||
<DropdownMenuItem onSelect={onRetryExecution} disabled={isRetryPending}>
|
||||
<Redo />
|
||||
Retry
|
||||
{isRetryPending ? 'Retrying...' : 'Retry'}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
|
||||
@@ -821,6 +821,7 @@ export default function Logs() {
|
||||
hasNext={selectedLogIndex < sortedLogs.length - 1}
|
||||
hasPrev={selectedLogIndex > 0}
|
||||
onRetryExecution={handleRetrySidebarExecution}
|
||||
isRetryPending={retryExecution.isPending}
|
||||
/>
|
||||
),
|
||||
[
|
||||
@@ -830,6 +831,7 @@ export default function Logs() {
|
||||
handleNavigateNext,
|
||||
handleNavigatePrev,
|
||||
handleRetrySidebarExecution,
|
||||
retryExecution.isPending,
|
||||
selectedLogIndex,
|
||||
sortedLogs.length,
|
||||
]
|
||||
@@ -1231,6 +1233,7 @@ export default function Logs() {
|
||||
onOpenPreview={handleOpenPreview}
|
||||
onCancelExecution={handleCancelExecution}
|
||||
onRetryExecution={handleRetryExecution}
|
||||
isRetryPending={retryExecution.isPending}
|
||||
onToggleWorkflowFilter={handleToggleWorkflowFilter}
|
||||
onClearAllFilters={handleClearAllFilters}
|
||||
isFilteredByThisWorkflow={isFilteredByThisWorkflow}
|
||||
|
||||
@@ -438,12 +438,19 @@ export function extractRetryInput(log: WorkflowLog): unknown | undefined {
|
||||
}
|
||||
|
||||
const executionState = execData.executionState as
|
||||
| { blockStates?: Record<string, { output?: unknown }> }
|
||||
| {
|
||||
blockStates?: Record<
|
||||
string,
|
||||
{ output?: unknown; executed?: boolean; executionTime?: number }
|
||||
>
|
||||
}
|
||||
| undefined
|
||||
if (!executionState?.blockStates) return undefined
|
||||
|
||||
// Starter/trigger blocks are pre-populated with executed: false and executionTime: 0,
|
||||
// which distinguishes them from blocks that actually ran during execution.
|
||||
for (const state of Object.values(executionState.blockStates)) {
|
||||
if (state.output && typeof state.output === 'object' && 'input' in state.output) {
|
||||
if (state.executed === false && state.executionTime === 0 && state.output != null) {
|
||||
return state.output
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,6 +372,9 @@ export class ExecutionLogger implements IExecutionLoggerService {
|
||||
? Math.max(0, Math.round(rawDurationMs))
|
||||
: 0
|
||||
|
||||
const redactedWorkflowInput =
|
||||
workflowInput !== undefined ? redactApiKeys(filterForDisplay(workflowInput)) : undefined
|
||||
|
||||
const completedExecutionData = this.buildCompletedExecutionData({
|
||||
existingExecutionData,
|
||||
traceSpans: redactedTraceSpans,
|
||||
@@ -380,7 +383,7 @@ export class ExecutionLogger implements IExecutionLoggerService {
|
||||
completionFailure,
|
||||
executionCost,
|
||||
executionState,
|
||||
workflowInput,
|
||||
workflowInput: redactedWorkflowInput,
|
||||
})
|
||||
|
||||
const [updatedLog] = await db
|
||||
|
||||
Reference in New Issue
Block a user