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
inA
will be available only after the creation of the beanB
. 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:
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, butCat
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.