Easier plugin debugging

- Make debugging syntax errors in plugins easier by catching the errors and printing relevant information
- Fix default plugin rejected load promise resolving unexpectedly
- Fix default plugin id not stripping the search part of the url
This commit is contained in:
KatieFrogs 2022-03-04 01:26:17 +03:00
parent 6c54c45a23
commit 89b159e33a

View File

@ -20,6 +20,10 @@ class Plugins{
var name = options.name
if(!name && isUrl){
name = script
var index = name.lastIndexOf("?")
if(index !== -1){
name = name.slice(0, index)
}
var index = name.lastIndexOf("/")
if(index !== -1){
name = name.slice(index + 1)
@ -50,6 +54,7 @@ class Plugins{
return plugin
}
remove(name){
if(name in this.pluginMap){
var hash = this.pluginMap[name].hash
if(hash){
var index = this.hashes.indexOf(hash)
@ -58,6 +63,7 @@ class Plugins{
}
}
this.unload(name)
}
var index = this.allPlugins.findIndex(obj => obj.name === name)
if(index !== -1){
this.allPlugins.splice(index, 1)
@ -235,12 +241,14 @@ class Plugins{
default: true,
getItem: () => plugin.started,
setItem: value => {
if(plugin.name in this.pluginMap){
if(plugin.started && !value){
this.stop(plugin.name)
}else if(!plugin.started && value){
this.start(plugin.name)
}
}
}
})
}
var settings = plugin.settings()
@ -321,9 +329,15 @@ class PluginLoader{
try{
this.module = new module.default()
}catch(e){
console.error(e)
this.error()
return
var error = new Error()
error.stack = "Error initializing plugin: " + this.name + "\n" + e.stack
if(loadErrors){
return Promise.reject(error)
}else{
console.error(error)
return Promise.resolve()
}
}
var output
try{
@ -334,22 +348,41 @@ class PluginLoader{
output = this.module.load(this)
}
}catch(e){
console.error(e)
this.error()
var error = new Error()
error.stack = "Error in plugin load: " + this.name + "\n" + e.stack
if(loadErrors){
return Promise.reject(error)
}else{
console.error(error)
return Promise.resolve()
}
}
if(typeof output === "object" && output.constructor === Promise){
return output.catch(e => {
console.error(e)
this.error()
var error = new Error()
error.stack = "Error in plugin load promise: " + this.name + (e ? "\n" + e.stack : "")
if(loadErrors){
return Promise.reject(error)
}else{
console.error(error)
return Promise.resolve()
}
})
}
}, e => {
console.error(e)
this.error()
if(loadErrors){
return Promise.reject(e)
if(e.name === "SyntaxError"){
var error = new SyntaxError()
error.stack = "Error in plugin syntax: " + this.name + "\n" + e.stack
}else{
var error = e
}
if(loadErrors){
return Promise.reject(error)
}else{
console.error(error)
return Promise.resolve()
}
})
@ -370,13 +403,15 @@ class PluginLoader{
this.module.start()
}
}catch(e){
console.error(e)
var error = new Error()
error.stack = "Error in plugin start: " + this.name + "\n" + e.stack
console.error(error)
this.error()
}
}
})
}
stop(orderChange, error){
stop(orderChange, noError){
if(this.loaded && this.started){
if(!orderChange){
var stopIndex = plugins.startOrder.indexOf(this.name)
@ -397,8 +432,10 @@ class PluginLoader{
this.module.stop()
}
}catch(e){
console.error(e)
if(!error){
var error = new Error()
error.stack = "Error in plugin stop: " + this.name + "\n" + e.stack
console.error(error)
if(!noError){
this.error()
}
}
@ -426,7 +463,9 @@ class PluginLoader{
this.module.unload()
}
}catch(e){
console.error(e)
var error = new Error()
error.stack = "Error in plugin unload: " + this.name + "\n" + e.stack
console.error(error)
}
delete this.module
}
@ -437,7 +476,9 @@ class PluginLoader{
try{
this.module.error()
}catch(e){
console.error(e)
var error = new Error()
error.stack = "Error in plugin error: " + this.name + "\n" + e.stack
console.error(error)
}
}
this.unload(true)
@ -481,9 +522,17 @@ class EditValue{
if(this.name){
this.original = this.name[0][this.name[1]]
}
try{
var output = this.loadCallback(this.original)
}catch(e){
console.error(this.loadCallback)
var error = new Error()
error.stack = "Error editing the value of " + this.getName() + "\n" + e.stack
throw error
}
if(typeof output === "undefined"){
throw new Error("A value is expected to be returned")
console.error(this.loadCallback)
throw new Error("Error editing the value of " + this.getName() + ": A value is expected to be returned")
}
if(this.name){
this.name[0][this.name[1]] = output
@ -500,6 +549,27 @@ class EditValue{
}
return this.original
}
getName(){
var name = "unknown"
try{
if(this.name){
var name = (
typeof this.name[0] === "function" && this.name[0].name
|| (
typeof this.name[0] === "object" && typeof this.name[0].constructor === "function" && (
this.name[0] instanceof this.name[0].constructor ? (() => {
var consName = this.name[0].constructor.name || ""
return consName.slice(0, 1).toLowerCase() + consName.slice(1)
})() : this.name[0].constructor.name + ".prototype"
)
) || name
) + (this.name[1] ? "." + this.name[1] : "")
}
}catch(e){
name = "error"
}
return name
}
unload(){
delete this.name
delete this.original
@ -513,11 +583,33 @@ class EditFunction extends EditValue{
this.original = this.name[0][this.name[1]]
}
var args = plugins.argsFromFunc(this.original)
try{
var output = this.loadCallback(plugins.strFromFunc(this.original), args)
if(typeof output === "undefined"){
throw new Error("A value is expected to be returned")
}catch(e){
console.error(this.loadCallback)
var error = new Error()
error.stack = "Error editing the function value of " + this.getName() + "\n" + e.stack
throw error
}
if(typeof output === "undefined"){
console.error(this.loadCallback)
throw new Error("Error editing the function value of " + this.getName() + ": A value is expected to be returned")
}
try{
var output = Function(...args, output)
}catch(e){
console.error(this.loadCallback)
var error = new SyntaxError()
var blob = new Blob([output], {
type: "application/javascript"
})
var url = URL.createObjectURL(blob)
error.stack = "Error editing the function value of " + this.getName() + ": Could not evaluate string, check the full string for errors: " + url + "\n" + e.stack
setTimeout(() => {
URL.revokeObjectURL(url)
}, 5 * 60 * 1000)
throw error
}
if(this.name){
this.name[0][this.name[1]] = output
}