Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error tooltips and logging 🤕 #32

Merged
merged 6 commits into from
Oct 4, 2018
Merged

Conversation

bengreenier
Copy link
Owner

@bengreenier bengreenier commented Oct 2, 2018

This adds all those fancy debugging and safety features you've been looking for! ✨

  • Handle plugins that fail to load (require('./path/to/plugin') fails)
  • Handle plugins that fail to render (React.createElement(Plugin) fails)
  • Log critical events
  • Default log level to verbose when NODE_ENV !== 'production'
  • fixes error handling when custom overlays fail #7

The logging uses electron-log which writes to:

on Linux: ~/.config/<app name>/log.log
on OS X: ~/Library/Logs/<app name>/log.log
on Windows: %USERPROFILE%\AppData\Roaming\<app name>\log.log

Plugin failures are communicated using the Tray.displayBalloon() electron api, as well as being written to the log.

Examples:

showing tooltip Plugin Render Error
[2018-10-02 10:52:38.229] [error] Failed to render clock located at V:\vs_workspace\overlayed\dist\app\plugin\Clock

showing tooltip Plugin Load Error
[2018-10-02 10:46:26.621] [error] Failed to load clock from V:\vs_workspace\overlayed\dist\app\plugin\Clock

@bengreenier bengreenier added the enhancement New feature or request label Oct 2, 2018
@bengreenier bengreenier added this to the 1.0.0 Release milestone Oct 2, 2018
@bengreenier bengreenier self-assigned this Oct 2, 2018
component: require(componentPath).default as React.ComponentType<any>
}} as IInstalledPlugin
try {
return {...plugin, ...{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can rewrite this to:

return {
  ...plugin,
  component: require(componentPath).default as React.ComponentType<any>
} as IInstalledPlugin

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is cool - i'm going to punt on this for now though, as there's quite a few places in the codebase that do this that deserve to be refactored at the same time. see #36


public componentDidCatch(error : Error) {
this.setState({ hasError: true })
this.props.onError(error)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this onError function dependent on state in anyway? If so you should consider moving line 11 into a callback function of the setState method on line 10.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not dependent, as such keeping as is for now

@@ -20,6 +24,7 @@ export class Plugin extends React.Component<IPluginProps, any> {
super(props)

this.onLabelLinkClicked = this.onLabelLinkClicked.bind(this)
this.onError = this.onError.bind(this)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid binding the component this you can declare your onError method differently. See how I do it here

Also check out the next comment on the onError function where I show you the proper rewrite.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, but punting for now as it requires a larger change across the codebase for consistency: #37

open(uri)
}
}
}

private onError(err : Error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewrite to

private onError = (err : Error) => { ... }

// install the uninstalled plugins
Promise.all(this.installPlugins(installNeeded)).then((installedPlugins) => {
// when these load, merge them in
this.setState({
plugins: this.state.plugins.concat(installedPlugins)
})
}, (error) => {
log.error(`failed installation: ${error}`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if error is an object it may be printed like so: failed installation: [object Object]
if it is an instance of Error then it will print like so: failed installation: Error: <message>

I recommend using error.message when logging errors through template strings

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer to refactor template content to expect Error: message than rely on a specific object shape here. will make the change - good catch!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like the only outstanding comment then its good to merge ✨

component: require(plugin.component).default as React.ComponentType<any>
}} as IInstalledPlugin)
try {
resolve({...plugin, ...{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above comment on better obj destructuring

@@ -0,0 +1,146 @@
import { app, ipcMain, Menu, MenuItem, nativeImage, Tray } from "electron"
import log from 'electron-log'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inconsistent quote characters. Surprised linter didn't yell at you for this.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same.

@@ -30,12 +31,14 @@ export class CompositeWindow extends BrowserWindow {

// notify react side
this.webContents.send(IPCMessageNames.ToggleEditMode, this.isInteractive)
log('toggled compositor interactivity')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throughout the previous code you are using log.info or log.error; why nothing here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

@bengreenier bengreenier merged commit 18b49b2 into master Oct 4, 2018
@bengreenier bengreenier deleted the feature/error-tooltips branch October 4, 2018 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

error handling when custom overlays fail
2 participants