Report uncaught Python exceptions with a GUI popup

This commit is contained in:
miruka 2019-12-26 09:20:51 -04:00
parent eff64fabd6
commit 511681ae4d
6 changed files with 77 additions and 10 deletions

View File

@ -3,6 +3,9 @@
- Make dark bar extend down pane - Make dark bar extend down pane
- Verify default size - Verify default size
- catch py unretrieved exception
- call default handler from signin & others
## Media ## Media
- nio ClientTimeout - nio ClientTimeout

View File

@ -21,8 +21,10 @@ HPopup {
property alias details: details property alias details: details
property string okText: qsTr("OK") property string okText: qsTr("OK")
property string okIcon: "ok"
property bool okEnabled: true property bool okEnabled: true
property bool okClicked: false property bool okClicked: false
property string cancelText: qsTr("Cancel")
Binding on height { Binding on height {
@ -40,8 +42,8 @@ HPopup {
clickButtonOnEnter: "ok" clickButtonOnEnter: "ok"
buttonModel: [ buttonModel: [
{ name: "ok", text: okText, iconName: "ok", enabled: okEnabled}, { name: "ok", text: okText, iconName: okIcon, enabled: okEnabled},
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel" }, { name: "cancel", text: cancelText, iconName: "cancel" },
] ]
buttonCallbacks: ({ buttonCallbacks: ({

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../Base"
BoxPopup {
summary.text: qsTr("Unexpected error occured: <i>%1</i>").arg(errorType)
summary.textFormat: Text.StyledText
okText: qsTr("Report")
okIcon: "report-error"
okEnabled: false // TODO
cancelText: qsTr("Ignore")
box.focusButton: "cancel"
property string errorType
property var errorArguments: []
property string traceback: ""
HScrollableTextArea {
text: traceback || qsTr("No traceback available")
area.readOnly: true
Layout.fillWidth: true
}
HCheckBox {
text: qsTr("Hide this type of error until restart")
onCheckedChanged:
checked ?
window.hideErrorTypes.add(errorType) :
window.hideErrorTypes.delete(errorType)
Layout.fillWidth: true
}
}

View File

@ -19,21 +19,39 @@ QtObject {
let onSuccess = py.privates.pendingCoroutines[uuid].onSuccess let onSuccess = py.privates.pendingCoroutines[uuid].onSuccess
let onError = py.privates.pendingCoroutines[uuid].onError let onError = py.privates.pendingCoroutines[uuid].onError
delete py.privates.pendingCoroutines[uuid]
if (error) { if (error) {
let type = py.getattr(py.getattr(error, "__class__"), "__name__") const type = py.getattr(py.getattr(error, "__class__"), "__name__")
let args = py.getattr(error, "args") const args = py.getattr(error, "args")
type === "CancelledError" ? if (type === "CancelledError") {
console.warn(`python: cancelled: ${uuid}`) : console.warn(`python: cancelled: ${uuid}`)
return
}
onError ? if (onError) {
onError(type, args, error, traceback) : onError(type, args, error, traceback)
return
}
console.error(`python: ${uuid}\n${traceback}`) console.error(`python: ${uuid}\n${traceback}`)
} else if (onSuccess) { onSuccess(result) } if (window.hideErrorTypes.has(type)) {
console.warn(
"Not showing error popup for this type due to user choice"
)
return
}
delete py.privates.pendingCoroutines[uuid] utils.makePopup(
"Popups/UnexpectedErrorPopup.qml",
window,
{ errorType: type, errorArguments: args, traceback },
)
}
if (onSuccess) onSuccess(result)
} }

View File

@ -44,6 +44,8 @@ ApplicationWindow {
property var theme: null property var theme: null
property var hideErrorTypes: new Set()
readonly property alias py: py readonly property alias py: py

View File

@ -0,0 +1,3 @@
<svg clip-rule="evenodd" fill-rule="evenodd" height="24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m24 17.98h-13l-7 5.02v-5.02h-4v-16.981h24zm-22-14.981v12.981h4v3.125l4.357-3.125h11.643v-12.981zm10 8.501c.69 0 1.25.56 1.25 1.25s-.56 1.25-1.25 1.25-1.25-.56-1.25-1.25.56-1.25 1.25-1.25zm1-6.5v5h-2v-5z"/>
</svg>

After

Width:  |  Height:  |  Size: 330 B