-
Notifications
You must be signed in to change notification settings - Fork 37
Closed as not planned
Labels
type/bugSomething isn't workingSomething isn't working
Description
What happened?
When creating a DataSource using Mixins, grafana logs the following error :
Uncaught (in promise)
Object { message: "Datasource: fd8841fb-5d9c-4e1c-aeb7-8c5489e83032 was not found" }
[actions.ts:174:2](webpack://grafana/public/app/features/datasources/state/actions.ts)
I tracked the bug down to this line
Typescript Mixins constructors MUST have a single rest parameter, therefore dsPlugin.DataSourceClass.length will be 0 instead of 1, incorrectly triggering the angular loading path.
What did you expect to happen?
Datasources built with mixins should work.
Did this work before?
I suppose not.
How do we reproduce it?
class Query {}
class Options {}
interface FooConstructor<
TFoo extends AbsFooAPI<TQuery, TOptions>,
TQuery extends Query = Query,
TOptions extends Options = Options,
> {
new (...args: any[]): TFoo;
}
// DatasourcePlugin
class FooPlugin<
TFoo extends AbsFooAPI<TQuery, TOptions>,
TQuery extends Query,
TOptions extends Options,
>{
private foo: TFoo
constructor(FooClass:FooConstructor<TFoo, TQuery, TOptions>){
this.foo = new FooClass()
}
process(){
console.log('Plugin')
this.foo.doFoo()
if (this.foo.doBar){
this.foo.doBar()
}
if (this.foo.doBaz){
this.foo.doBaz()
}
}
}
// DatasourceAPI
abstract class AbsFooAPI<TQuery extends Query, TOptions extends Options> {
constructor(arg1:string){}
abstract doFoo():void
doBar?():void;
doBaz?():void;
}
// DatasourceWithBackend
class Foo<
TQuery extends Query = Query,
TOptions extends Options = Options,
> extends AbsFooAPI<TQuery, TOptions>
{
constructor(arg1:string){
super(arg1)
}
doFoo():void {
console.log("Done Foo");
}
}
// My Datasource base
class FooBar extends Foo {
constructor(arg1:string){
super(arg1)
}
doBar():void{
console.log('Done Bar')
}
}
// My datasource feature mixin
type GConstructor<T = {}> = new (...args: any[]) => T;
function withBaz<T extends GConstructor<FooBar>>(Base : T){
return class extends Base {
// A mixin constructor must have only one rest parameter of type any[]
// A constructor with a positional parameter breaks the mixin contract
// constructor(first: any, ...args:any[]){
// super(first, ...args)
// }
doBaz():void{
console.log('Done Baz')
}
}
}
class MyQuery extends Query {}
class MyOptions extends Options {}
const FooBarBaz = withBaz(FooBar)
const fbb = new FooBarBaz('settings')
const plugin = new FooPlugin<InstanceType<typeof FooBarBaz>,MyQuery,MyOptions>(FooBarBaz)
plugin.process()
console.log("AbsFooAPI LENGTH", AbsFooAPI.length)
console.log("Foo LENGTH", Foo.length)
console.log("FooBar LENGTH", FooBar.length)
console.log("FooBarBaz LENGTH", FooBarBaz.length)This example replicates the structure of a DataSource plugin and showcases how the use of mixins breaks the assumption on the constructor's length.
Transposing it onto a real plugin should be trivial.
Is the bug inside a dashboard panel?
No response
Environment (with versions)?
Grafana: Grafana v10.3.3 (252761264e)
OS: Ubuntu 23.04
Browser: Firefox 122.0
Grafana platform?
Docker
Datasource(s)?
No response
Metadata
Metadata
Assignees
Labels
type/bugSomething isn't workingSomething isn't working
Type
Projects
Status
🚀 Shipped