Skip to content

Commit 7cbdfa0

Browse files
committed
Wrap API error / warning logging for userfriend and advanced outputs
1 parent 854b1e4 commit 7cbdfa0

14 files changed

Lines changed: 74 additions & 67 deletions

File tree

src/main/frontend/app/components/file-structure/editor-data-provider.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { TreeItem, TreeItemIndex } from 'react-complex-tree'
22
import type { FileTreeNode } from '~/types/filesystem.types'
33
import { fetchProjectRootTree, fetchDirectoryByPath } from '~/services/file-tree-service'
4+
import { logApiWarning } from '~/utils/logger';
45
import { sortChildren } from './tree-utilities'
56
import type { DataProviderLike } from './use-file-tree-context-menu'
67
import { BaseFilesDataProvider } from './base-files-data-provider'
@@ -50,7 +51,7 @@ export default class EditorFilesDataProvider extends BaseFilesDataProvider<FileN
5051
const tree = await fetchProjectRootTree(this.projectName)
5152

5253
if (!tree) {
53-
console.warn('[EditorFilesDataProvider] Received empty tree from API')
54+
console.warn('Received empty tree from API')
5455
this.data = {}
5556
return
5657
}
@@ -66,7 +67,7 @@ export default class EditorFilesDataProvider extends BaseFilesDataProvider<FileN
6667
this.loadedDirectories.add(tree.path)
6768
this.notifyListeners(['root'])
6869
} catch (error) {
69-
console.error('[EditorFilesDataProvider] Unexpected error loading tree:', error)
70+
logApiWarning('Unexpected error loading project file tree', error as Error)
7071
this.data = {}
7172
this.notifyListeners(['root'])
7273
}
@@ -80,15 +81,15 @@ export default class EditorFilesDataProvider extends BaseFilesDataProvider<FileN
8081
try {
8182
const directory = await fetchDirectoryByPath(this.projectName, item.data.path)
8283
if (!directory) {
83-
console.warn('[EditorFilesDataProvider] Received empty directory from API')
84+
console.warn('Received empty directory from API')
8485
return
8586
}
8687

8788
item.children = this.buildChildren(itemId, directory.children)
8889
this.loadedDirectories.add(item.data.path)
8990
this.notifyListeners([itemId])
9091
} catch (error) {
91-
console.error('Failed to load directory', error)
92+
logApiWarning('Failed to load directory', error as Error)
9293
}
9394
}
9495

src/main/frontend/app/components/file-structure/studio-files-data-provider.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { TreeItemIndex } from 'react-complex-tree'
2+
import { logApiError } from '~/utils/logger';
23
import { sortChildren } from './tree-utilities'
34
import { fetchProjectTree, fetchDirectoryByPath } from '~/services/file-tree-service'
45
import type { FileTreeNode } from '~/types/filesystem.types'
@@ -62,7 +63,7 @@ export default class FilesDataProvider extends BaseFilesDataProvider<StudioItemD
6263
const tree = await fetchProjectTree(this.projectName)
6364

6465
if (!tree) {
65-
console.warn('[StudioFilesDataProvider] Received empty tree from API')
66+
console.warn('Received empty tree from API')
6667
this.data = {}
6768
return
6869
}
@@ -96,15 +97,15 @@ export default class FilesDataProvider extends BaseFilesDataProvider<StudioItemD
9697

9798
const directory = await fetchDirectoryByPath(this.projectName, path)
9899
if (!directory) {
99-
console.warn('[StudioFilesDataProvider] Received empty directory from API')
100+
console.warn('Received empty directory from API')
100101
return
101102
}
102103

103104
item.children = sortChildren(directory.children).map((child) => this.buildChildItem(itemId, child))
104105
this.loadedDirectories.add(path)
105106
this.notifyListeners([itemId])
106107
} catch (error) {
107-
console.error(`Failed to load directory for ${path}`, error)
108+
logApiError(`Failed to load directory for ${path}`, error as Error)
108109
}
109110
}
110111

src/main/frontend/app/components/file-structure/use-file-tree-context-menu.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import { createFolderInProject } from '~/services/file-tree-service'
55
import { clearConfigurationFileCache } from '~/services/configuration-file-service'
66
import useTabStore from '~/stores/tab-store'
77
import useEditorTabStore from '~/stores/editor-tab-store'
8-
import { showErrorToast, showErrorToastFrom } from '~/components/toast'
8+
import { showErrorToast } from '~/components/toast'
99
import { FILE_NAME_PATTERNS, FOLDER_OR_ADAPTER_NAME_PATTERNS } from '~/components/file-structure/name-input-dialog'
10+
import { logApiError } from '~/utils/logger';
1011

1112
export interface ContextMenuState {
1213
position: { x: number; y: number }
@@ -128,7 +129,7 @@ export function useFileTreeContextMenu({
128129
await createFile(projectName, `${parentPath}/${name}`)
129130
await dataProvider.reloadDirectory(parentItemId)
130131
} catch (error) {
131-
showErrorToastFrom('Failed to create file', error)
132+
logApiError('Failed to create file', error as Error)
132133
}
133134
setNameDialog(null)
134135
},
@@ -153,7 +154,7 @@ export function useFileTreeContextMenu({
153154
await createFolderInProject(projectName, `${parentPath}/${name}`)
154155
await dataProvider.reloadDirectory(parentItemId)
155156
} catch (error) {
156-
showErrorToastFrom('Failed to create folder', error)
157+
logApiError('Failed to create folder', error as Error)
157158
}
158159
setNameDialog(null)
159160
},
@@ -193,7 +194,7 @@ export function useFileTreeContextMenu({
193194
await dataProvider.reloadDirectory(getParentItemId(itemId))
194195
onAfterRename?.(oldPath, newName)
195196
} catch (error) {
196-
showErrorToastFrom('Failed to rename', error)
197+
logApiError('Failed to rename', error as Error)
197198
}
198199
setNameDialog(null)
199200
},
@@ -228,7 +229,7 @@ export function useFileTreeContextMenu({
228229
useEditorTabStore.getState().refreshAllTabs()
229230
onAfterDelete?.(deleteTarget.path)
230231
} catch (error) {
231-
showErrorToastFrom('Failed to delete', error)
232+
logApiError('Failed to delete', error as Error)
232233
}
233234

234235
await dataProvider.reloadDirectory(deleteTarget.parentItemId)

src/main/frontend/app/components/file-structure/use-studio-context-menu.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { createFolderInProject } from '~/services/file-tree-service'
55
import { createAdapter, renameAdapter, deleteAdapter } from '~/services/adapter-service'
66
import { clearConfigurationFileCache, createConfigurationFile } from '~/services/configuration-file-service'
77
import useTabStore from '~/stores/tab-store'
8-
import { showErrorToastFrom } from '~/components/toast'
8+
import { logApiError } from '~/utils/logger';
99
import type { StudioItemData, StudioFolderData, StudioAdapterData } from './studio-files-data-provider'
1010
import {
1111
CONFIGURATION_NAME_PATTERNS,
@@ -183,7 +183,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
183183
await createConfigurationFile(projectName, relativePath)
184184
await dataProvider.reloadDirectory('root')
185185
} catch (error) {
186-
showErrorToastFrom('Failed to create configuration', error)
186+
logApiError('Failed to create configuration', error as Error)
187187
}
188188
setNameDialog(null)
189189
},
@@ -206,7 +206,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
206206
await createAdapter(projectName, name, menu.path)
207207
await dataProvider.reloadDirectory('root')
208208
} catch (error) {
209-
showErrorToastFrom('Failed to create adapter', error)
209+
logApiError('Failed to create adapter', error as Error)
210210
}
211211
setNameDialog(null)
212212
},
@@ -229,7 +229,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
229229
await createFolderInProject(projectName, `${menu.folderPath}/${name}`)
230230
await dataProvider.reloadDirectory('root')
231231
} catch (error) {
232-
showErrorToastFrom('Failed to create folder', error)
232+
logApiError('Failed to create folder', error as Error)
233233
}
234234
setNameDialog(null)
235235
},
@@ -268,7 +268,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
268268
}
269269
await dataProvider.reloadDirectory('root')
270270
} catch (error) {
271-
showErrorToastFrom('Failed to rename', error)
271+
logApiError('Failed to rename', error as Error)
272272
}
273273
setNameDialog(null)
274274
},
@@ -305,7 +305,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
305305
useTabStore.getState().removeTabsForConfig(deleteTarget.path)
306306
}
307307
} catch (error) {
308-
showErrorToastFrom('Failed to delete', error)
308+
logApiError('Failed to delete', error as Error)
309309
}
310310
await dataProvider.reloadDirectory('root')
311311
setDeleteTarget(null)

src/main/frontend/app/components/git/git-panel.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import {
1010
pullChanges,
1111
refreshOpenDiffs,
1212
} from '~/services/git-service'
13-
import { showErrorToastFrom, showInfoToast, showSuccessToast, showErrorToast } from '~/components/toast'
13+
import { showInfoToast, showSuccessToast, showErrorToast } from '~/components/toast'
1414
import useEditorTabStore from '~/stores/editor-tab-store'
15+
import { logApiError } from '~/utils/logger'
1516
import GitToolbar from './git-toolbar'
1617
import GitChanges from './git-changes'
1718
import GitCommitBox from './git-commit-box'
@@ -45,7 +46,7 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps)
4546
const newStatus = await fetchGitStatus(projectName)
4647
setStatus(newStatus)
4748
} catch (error) {
48-
showErrorToastFrom('Failed to fetch git status', error)
49+
logApiError('Failed to fetch git status', error as Error)
4950
}
5051
}, [projectName, setStatus])
5152

@@ -77,7 +78,7 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps)
7778
})
7879
editorTabStore.setActiveTab(tabId)
7980
} catch (error) {
80-
showErrorToastFrom('Failed to load diff', error)
81+
logApiError('Failed to load diff', error as Error)
8182
}
8283
},
8384
[projectName, setSelectedFile, setFileDiff, initFileHunks],
@@ -124,7 +125,7 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps)
124125
await refreshOpenDiffs(projectName)
125126
showSuccessToast(`Committed: ${result.commitId.slice(0, 7)}`)
126127
} catch (error) {
127-
showErrorToastFrom('Failed to commit', error)
128+
logApiError('Failed to commit', error as Error)
128129
} finally {
129130
setIsLoading(false)
130131
}
@@ -144,7 +145,7 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps)
144145
}
145146
await refreshStatus()
146147
} catch (error) {
147-
showErrorToastFrom('Failed to push', error)
148+
logApiError('Failed to push', error as Error)
148149
}
149150
}, [projectName, token, refreshStatus, status?.ahead])
150151

@@ -165,7 +166,7 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps)
165166
await refreshStatus()
166167
await refreshOpenDiffs(projectName)
167168
} catch (error) {
168-
showErrorToastFrom('Failed to pull', error)
169+
logApiError('Failed to pull', error as Error)
169170
}
170171
}, [projectName, token, refreshStatus])
171172

src/main/frontend/app/components/toast.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ export function showErrorToast(message: string, title = 'Error') {
7171
showToast({ type: 'ERROR', title, message })
7272
}
7373

74-
/** Shows an error toast with a prefix, extracting the message from an unknown error. */
75-
export function showErrorToastFrom(prefix: string, error: unknown) {
76-
showErrorToast(`${prefix}: ${error instanceof Error ? error.message : String(error)}`)
77-
}
78-
7974
export function Toast() {
8075
const [toast, setToast] = useState<ToastOptions | null>(null)
8176
const theme = useTheme()

src/main/frontend/app/providers/frankconfig-xsd-provider.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'
22
import { fetchFrankConfigXsd } from '~/services/xsd-service'
3+
import {logApiWarning} from "~/utils/logger";
34

45
interface FrankConfigXsdContextValue {
56
xsdContent: string | null
@@ -13,7 +14,7 @@ export function FrankConfigXsdProvider({ children }: { children: ReactNode }) {
1314
useEffect(() => {
1415
fetchFrankConfigXsd()
1516
.then(setXsdContent)
16-
.catch((error) => console.error('Failed to load FrankConfig XSD:', error))
17+
.catch((error) => logApiWarning('Failed to load FrankConfig XSD:', error as Error))
1718
}, [])
1819

1920
return <FrankConfigXsdContext.Provider value={{ xsdContent }}>{children}</FrankConfigXsdContext.Provider>

src/main/frontend/app/routes/datamapper/property-list.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,10 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
156156
setEditingMapping,
157157
openMapping,
158158
})
159-
//Don't add flow as dependancy here, it'll become an infinite loop flow changes every rerender --> updates the memo --> the memo updates the nodetypes --> updating the nodetypes causes react to trigger a rerender resulting in a infinite loop
159+
//UseMemo is used here to ensure nodetype is not changed throughout rerenders. If the variable is updated reactflow throws a warning in the console;
160+
//Don't add flow as dependency here, it'll become an infinite loop flow changes every rerender --> updates the memo --> the memo updates the nodetypes --> updating the nodetypes causes react to trigger a rerender resulting in a infinite loop
160161
// eslint-disable-next-line react-hooks/exhaustive-deps
161-
}, [openMapping]) //UseMemo is used here to ensure nodetype is not changed throughout rerenders. If the variable is updated reactflow throws a warning in the console;
162+
}, [openMapping])
162163

163164
useEffect(() => {
164165
if (!reactFlowInstance) return
@@ -171,7 +172,6 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
171172

172173
window.addEventListener('resize', updateSize)
173174

174-
// delay initial run
175175
requestAnimationFrame(updateSize)
176176

177177
return () => {
@@ -189,14 +189,13 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
189189
})
190190
}, [reactFlowNodes, edges, reactFlowInstance, configDispatch])
191191

192-
//Updates the outer canvas whenever something is added
193192
useEffect(() => {
194193
setCanvasSize((size) => updateCanvasSize(reactFlowNodes, size))
195194
}, [reactFlowNodes])
196195

197196
const onRestore = useCallback(() => {
198197
const restoreFlow = async () => {
199-
if (config.propertyData) await flow.importJsonConfiguration(JSON.stringify(config.propertyData))
198+
if (config.propertyData) flow.importJsonConfiguration(JSON.stringify(config.propertyData))
200199
}
201200

202201
restoreFlow().then(() => {
@@ -258,8 +257,8 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
258257
)
259258

260259
function openMappingModal(sources: NodeLabels[], targets: NodeLabels[]) {
261-
setMappingSources(sources.filter((s) => s.id?.includes('item')))
262-
setMappingTargets(targets.filter((t) => t.id?.includes('item')))
260+
setMappingSources(sources.filter((source) => source.id?.includes('item')))
261+
setMappingTargets(targets.filter((target) => target.id?.includes('item')))
263262
setAddMappingModal(true)
264263
}
265264

@@ -286,7 +285,7 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
286285
}
287286
setEditingNode(null)
288287
setAddFieldModal(false)
289-
showSuccessToast('Added property succesfully!')
288+
showSuccessToast('Added property successfully')
290289
} catch (error) {
291290
if (error instanceof Error) {
292291
showErrorToast(error.message)
@@ -307,7 +306,7 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
307306
setEdges(updatedEdges)
308307
setEditingMapping(null)
309308
setAddMappingModal(false)
310-
showSuccessToast('Added mapping succesfully!')
309+
showSuccessToast('Added mapping successfully')
311310
setReactFlowNodes((previous) =>
312311
previous.map((node) => ({
313312
...node,
@@ -343,10 +342,7 @@ function PropertyList({ config, configDispatch }: PropertyListProperties) {
343342
</div>
344343

345344
<div className="flex w-full justify-center overflow-auto">
346-
<div
347-
style={{ height: canvasSize.height }} //Using inline style for height because Tailwind doesn't support dynamic pixel values
348-
className="flex w-full flex-col items-center"
349-
>
345+
<div style={{ height: canvasSize.height }} className="flex w-full flex-col items-center">
350346
<ReactFlow
351347
nodeTypes={nodeTypes}
352348
nodes={reactFlowNodes.map((node) => ({

src/main/frontend/app/routes/datamapper/root.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ export default function Root() {
7575
<button
7676
className="border-border hover:bg-hover active:bg-selected hidden w-48 rounded-md border bg-red-500 px-4 py-2 text-sm"
7777
onClick={() => {
78-
console.dir(mappingListConfig)
79-
showSuccessToast('Logging config to console!', 'Debug')
78+
console.log(mappingListConfig)
79+
showSuccessToast('Logging config to console', 'Debug')
8080
}}
8181
>
8282
Test External node log

0 commit comments

Comments
 (0)