Files
modeling-app/src/lib/exceptions.ts
Kevin Nadro 029f76f273 Nadro/4857/wasm panic catching errors (#4901)
* chore: skeleton code to initialize and detect the global WASM panic

* chore: implementing a reimport method to fix the wasm instance being bricked

* fix: cleaning up tsc/lint

* fix: renaming file to be more accurate

* fix: added toast message

* fix: types...

* fix: typed the functions with arg spreads
2025-01-08 15:58:41 +00:00

52 lines
1.9 KiB
TypeScript

import { kclManager } from 'lib/singletons'
import { reloadModule, getModule } from 'lib/wasm_lib_wrapper'
import toast from 'react-hot-toast'
import { reportRejection } from './trap'
let initialized = false
/**
* WASM/Rust runtime can panic and the original try/catch/finally blocks will not trigger
* on the await promise. The interface will killed. This means we need to catch the error at
* the global/DOM level. This will have to interface with whatever controlflow that needs to be picked up
* within the error branch in the typescript to cover the application state.
*/
export const initializeWindowExceptionHandler = () => {
if (window && !initialized) {
window.addEventListener('error', (event) => {
void (async () => {
if (matchImportExportErrorCrash(event.message)) {
// do global singleton cleanup
kclManager.executeAstCleanUp()
toast.error(
'You have hit a KCL execution bug! Put your KCL code in a github issue to help us resolve this bug.'
)
try {
await reloadModule()
await getModule().default()
} catch (e) {
console.error('Failed to initialize wasm_lib')
console.error(e)
}
}
})().catch(reportRejection)
})
// Make sure we only initialize this event listener once
initialized = true
} else {
console.error(
`Failed to initialize, window: ${window}, initialized:${initialized}`
)
}
}
/**
* Specifically match a substring of the message error to detect an import export runtime issue
* when the WASM runtime panics
*/
const matchImportExportErrorCrash = (message: string): boolean => {
// called `Result::unwrap_throw()` on an `Err` value
const substringError = '`Result::unwrap_throw()` on an `Err` value'
return message.indexOf(substringError) !== -1 ? true : false
}