Skip to main content

Errorsโ€‹

Clawject produces few types of errors compile-time and runtime.

Compile-timeโ€‹

Each compile time error has own code that can be used to identify it. Each code is unique and consists of prefix CE and number. Example: CE7.

CE1: IncorrectNameErrorโ€‹

It occurs when the name of the element is empty.

Solution: Add name to the element.

CE2: DecoratorErrorโ€‹

It can occur when decorators applied incorrectly. Example:

@ClawjectApplication
@Bean //<- Bean cannot be applied to the class
class Application {
//Duplicate decorators
@Bean @Bean
cat = new Cat();

//Bean cannot be combined with PostConstruct
@Bean @PostConstruct
dog(): Dog {
return new Dog();
}
}

Solution: Fix such issues.

CE3: TypeQualifyErrorโ€‹

It occurs when Clawject can't qualify a type of element or return type of method or function.

Solution: Specify the type of element explicitly or verify that the type is correct.

CE4: CanNotRegisterBeanErrorโ€‹

It occurs when the element can't be registered as a bean because some of the bean dependencies could not be resolved. This error appears directly on bean declaration in @Configuration/@ClawjectApplication classes.

Solution:

  • Define missing dependencies in the context.
  • Check a topic about how dependencies are resolved
  • If more than one matching dependency is defined - rename parameter to match one of the resolved dependencies by name.
  • Specify primary bean for the dependency with @Primary decorator.

CE5: BeanCandidateNotFoundErrorโ€‹

It occurs when the bean candidate for the specific dependency could not be resolved.

  • When declaring bean with @Bean decorator - error will appear on the corresponding parameter of the factory-function.
  • When declaring bean with Bean function - error will appear on the corresponding parameter of the class constructor. If application has more than one matching candidate, for injection - Clawject will identify candidates that are matching by name and type.

Solution:

  • Define missing dependencies in the context.
  • Check a topic about how dependencies are resolved
  • If more than one matching dependency is defined - rename parameter to match one of the resolved dependencies by name.
  • Specify primary bean for the dependency with @Primary decorator.

CE6: MissingInitializerErrorโ€‹

It occurs when a property or method registered as a bean or lifecycle hook does not have an initializer. Example:

@ClawjectApplication
class Application {
@Bean cat: Cat;
@PostConstruct postConstruct(): void;
}

Solution: Add initializer to the property or method.

CE7: CircularDependenciesErrorโ€‹

It occurs when some beans have circular dependencies between each other. A circular dependency occurs when a bean A depends on another bean B, and the bean B depends on bean A as well:
Bean A โ†’ Bean B โ†’ Bean A

Of course, you could have more beans implied:
Bean A โ†’ Bean B โ†’ Bean C โ†’ Bean D โ†’ Bean E โ†’ Bean A

Example:

class A {
constructor(b: B) {}
}
class B {
constructor(a: A) {}
}

@ClawjectApplication
class Application {
//Error here
@Bean A(b: B): A {
return new A(b);
}
@Bean B(a: A): B {
return new B(a);
}
}

Clawject will detect circular dependencies at compile-time and report this error in a readable way.

Solution:

  • Redesign. When you have a circular dependency, itโ€™s likely there is a design problem and that the responsibilities are not well separated. Try to redesign the components properly so that their hierarchy is well-designed, and there is no need for circular dependencies.
  • If you canโ€™t redesign the components, it's possible to assign the instance after creation. It's not the best way, but it works. Note that field b in A will be available only after the creation of the bean B. Example:
    class A {
    declare public b: B;
    }
    class B {
    constructor(a: A) {}
    }
    @ClawjectApplication
    class Application {
    @Bean A(): A {
    return new A();
    }
    @Bean B(a: A): B {
    const instance = new B(a);
    a.b = instance;

    return instance;
    }
    }

CE8: IncorrectTypeErrorโ€‹

It occurs when the type of the bean is not supported by Clawject, here defined restricted Bean types. Example:

@ClawjectApplication
class Application {
@Bean undefinedBean(): undefined {
return undefined;
}
}

Solution: Use only supported types or wrap an unsupported type in the object. Example:

class Value<T> {
constructor(public value: T) {}
}
@ClawjectApplication
class Application {
@Bean undefinedBean(): Value<undefined> {
return new Value(undefined);
}
}

CE9: CorruptedMetadataErrorโ€‹

It occurs when class metadata is corrupted. It was altered manually or by some other tool. It can appear only in declaration files.

Example:

application.d.ts
export declare class Application {
foo: number;
bar: (foo: number) => number;
#_clawject_metadata: MyOwnDeclaredMetadata;
}

interface MyOwnDeclaredMetadata {
kind: 3;
version: 42;
///...
}

declare namespace ClawjectMetadata_1 {
export type Application_1 = {
kind: 2;
version: 1;
external: null;
beans: [
{ kind: 4; primary: false; external: null; qualifier: null; nestedProperty: null; classPropertyName: "foo"; },
{ kind: 3; primary: false; external: null; qualifier: null; nestedProperty: null; classPropertyName: "bar"; }
];
imports: [];
};
}

Solution: Do not edit generated files, regenerate declaration file.

CE10: DependencyResolvingErrorโ€‹

It occurs when the dependencies of bean could not be resolved. Examples:

  • Didn't pass class to the Bean function:
    @ClawjectApplication
    class Application {
    cat = Bean();
    }
  • More than one or no class declaration found, Dog class is declared, but Cat is not:
    class Dog {}

    @ClawjectApplication
    class Application {
    cat = Bean(Cat);
    dog = Bean(Dog);
    }

Solution: Try to specify the class explicitly or verify that the class is correct.

CE11: NotSupportedErrorโ€‹

It occurs when some feature is not supported by Clawject. Example:

  • Using @PostConstruct decorator on method with arguments outside Configuration class:
    class Cat {
    @PostConstruct
    meow(data: any): void {}
    }
  • Using @Embedded decorator with bean declared with Bean function:
    @ClawjectApplication
    class Application {
    @Embedded cat = Bean(Cat);
    }
  • Unsupported bean modifiers:
    @ClawjectApplication
    class Application {
    static cat1 = Bean(Cat);
    abstract cat2 = Bean(Cat);
    private cat3 = Bean(Cat);
    }
  • Using decorators in inappropriate places, for example @Bean decorator in not @Configuration/@ClawjectApplication class:
    class Dog {}
    class Cat {
    @Bean
    dog(): Dog {}
    }
  • Inappropriate decorators combination:
    @Bean @Embedded
    @ClawjectApplication
    class Application {
    @Bean @PostConstruct cat = Bean(Cat);
    }
  • Inappropriate decorator target:
    @Bean
    class Application {}

Solution: Do not use unsupported features.

CE12: BeanExposingErrorโ€‹

It occurs when you try to expose bean by the same name more than once. Example:

class IFoo {}
class Foo implements IFoo {}

@ClawjectApplication
class Application {
foo = Bean(Foo);

exposed1 = ExposeBeans<{ foo: Foo }>();
exposed2 = ExposeBeans<{ foo: IFoo }>();
}

Solution: Rename one of the exposed elements.

CE13: ConfigurationImportErrorโ€‹

It occurs when Clawject cannot resolve class which you're trying to import. Example:

@ClawjectApplication
class Application {
foo = Import(FooConfiguration); //FooConfiguration is not defined
}

Solution: Define missing class.

CE14: DuplicateNameErrorโ€‹

It occurs when few beans have the same name (class member name or name defined via @Qualifier decorator). Example:

@ClawjectApplication
class Application {
cat = Bean(Cat);
@Qualifier('cat') dog = Bean(Dog);
}

Solution: Change the name of one of the beans.

CE15: NotStaticallyKnownErrorโ€‹

It occurs when value or name in some part of the code is not statically known. Example:

  • The name of element is computed or uniq Symbol:
    const BeanName = 'MasyaCat';
    const symbol = Symbol.for('MasyaCat');
    @ClawjectApplication
    class Application {
    ['Masya' + 'Cat'] = Bean(Cat);
    [BeanName] = Bean(Cat);
    [symbol] = Bean(Cat);
    }
  • Arguments on some decorators are computed:
    @ClawjectApplication
    class Application {
    @Qualifier('Masya' + 'Cat') cat = Bean(Cat);
    }

Solution: Use only statically known values and names when it's required.

Runtimeโ€‹

Runtime errors are regular JavaScript errors that can be thrown during the application execution. Clawject exporting Error classes that can be caught and handled in the application code. Each error has name property, so it can be identified via name or via instanceof operator.

ExposedBeanNotFoundErrorโ€‹

It occurs when the exposed bean that is requested is not found in the application context. This error should not appear if everything is configured correctly and any generated file was not edited manually.

CorruptedMetadataErrorโ€‹

It occurs when class metadata is corrupted because it was altered manually or by some other tool.

Solution: Do not edit generated files, regenerate file.

DuplicateScopeErrorโ€‹

It occurs when you're trying to register the scope that is already registered. Example:

class MyScope implements Scope {
//...
}
ScopeRegister.registerScope('my-scope', new MyScope());
ScopeRegister.registerScope('my-scope', new MyScope());

Solution: Do not register the same scope more than once.

IllegalArgumentErrorโ€‹

It occurs when an incorrect argument is passed to some method or function. Example:

@ClawjectApplication
class MyApplication {
importedFunction = Import('non-constructable-value');
}

Solution: Pass only expected arguments.

IllegalStateErrorโ€‹

It's an internal error that should never happen, it occurs when the application is in an illegal state.

Solution: Report an issue.

NoClassMetadataFoundErrorโ€‹

It can occur if you passing class that is not annotated with @ClawjectApplication to the ClawjectFactory.createApplicationContext method.

Solution: Pass only classes annotated with @ClawjectApplication.

CouldNotBeProxiedErrorโ€‹

It occurs when your scope implementation defines useProxy method that is returned true, and bean that is returned value that could not be proxied was decorated with this scope. JavaScript does not allow wrapping primitive values in proxy, and clawject not supports proxies on functions, so this error will be thrown. Example:

class MyCustomScope implements Scope {
useProxy(): boolean {
return true;
}
//...
}
@ClawjectApplication
class Application {
@Bean @Scope('MyCustomScope') cat = 'Masya';
@Bean @Scope('MyCustomScope') catFunction = () => () => 'Masya';
}
ContainerManager.registerScope('MyCustomScope', new MyCustomScope());
await ClawjectFactory.createApplicationContext(Application);

Solution: Wrap value in the object or class.

ScopeIsNotRegisteredErrorโ€‹

It occurs when you're trying to assign non-registered scope to the bean. Example:

@ClawjectApplication
class Application {
@Scope('MySuperScopeThatIsNotRegistered') cat = Bean(Cat);
}

Solution: Register scope before using it.

UsageWithoutConfiguredDIErrorโ€‹

It occurs when you're trying to use Clawject without proper configuration, for example - you're forgotten to add Clawject transformer to the tsconfig.json file.

Solution: Configure Clawject properly.