or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-startup.mdcontext-management.mddependency-injection.mderror-handling.mdindex.mdlogging-system.mdmodule-system.mdqualifiers-parameters.mdscoping-lifecycle.md

error-handling.mddocs/

0

# Error Handling and Diagnostics

1

2

Comprehensive error handling with specific exception types for different failure scenarios in dependency injection and container management.

3

4

## Capabilities

5

6

### Definition and Resolution Errors

7

8

Handle errors related to dependency definition and resolution failures.

9

10

```javascript { .api }

11

/**

12

* Exception thrown when definition is not found during resolution

13

*/

14

class NoDefinitionFoundException extends Error {

15

/**

16

* Create exception for missing definition

17

* @param message - Error description

18

*/

19

constructor(message: string);

20

21

/**

22

* The qualifier that was not found (if any)

23

*/

24

qualifier?: Qualifier;

25

26

/**

27

* The type that was being resolved

28

*/

29

type?: any;

30

}

31

32

/**

33

* Exception thrown when definition override is not allowed

34

*/

35

class DefinitionOverrideException extends Error {

36

/**

37

* Create exception for definition override conflict

38

* @param message - Error description

39

*/

40

constructor(message: string);

41

42

/**

43

* The definition that conflicts

44

*/

45

definition?: BeanDefinition<any>;

46

}

47

48

/**

49

* Exception thrown when instance creation fails

50

*/

51

class InstanceCreationException extends Error {

52

/**

53

* Create exception for instance creation failure

54

* @param message - Error description

55

* @param cause - Underlying cause of failure

56

*/

57

constructor(message: string, cause?: Error);

58

59

/**

60

* The underlying cause of the creation failure

61

*/

62

cause?: Error;

63

64

/**

65

* The definition that failed to create instance

66

*/

67

definition?: BeanDefinition<any>;

68

}

69

```

70

71

**Usage Examples:**

72

73

```javascript

74

import {

75

GlobalContext,

76

NoDefinitionFoundException,

77

DefinitionOverrideException,

78

InstanceCreationException,

79

named

80

} from "koin-core";

81

82

class ServiceManager {

83

async getService(serviceName) {

84

try {

85

const koin = GlobalContext.get();

86

return koin.get(named(serviceName));

87

88

} catch (error) {

89

if (error instanceof NoDefinitionFoundException) {

90

console.error(`Service '${serviceName}' not found in DI container`);

91

console.error(`Qualifier: ${error.qualifier?.value}`);

92

console.error(`Type: ${error.type?.name}`);

93

94

// Provide fallback or default service

95

return this.createFallbackService(serviceName);

96

97

} else if (error instanceof InstanceCreationException) {

98

console.error(`Failed to create service '${serviceName}'`);

99

console.error(`Cause: ${error.cause?.message}`);

100

101

// Log additional context and re-throw

102

this.logCreationFailure(error);

103

throw new Error(`Service creation failed: ${error.message}`);

104

105

} else {

106

// Re-throw unknown errors

107

throw error;

108

}

109

}

110

}

111

112

registerService(serviceName, factory, allowOverride = false) {

113

try {

114

const koin = GlobalContext.get();

115

const module = module((builder) => {

116

builder.single(named(serviceName), factory);

117

});

118

119

if (allowOverride) {

120

// Handle override explicitly

121

koin.declare(factory(), named(serviceName), [], true);

122

} else {

123

loadKoinModules([module]);

124

}

125

126

} catch (error) {

127

if (error instanceof DefinitionOverrideException) {

128

console.error(`Service '${serviceName}' already exists`);

129

console.error(`Existing definition: ${error.definition?.qualifier?.value}`);

130

131

if (allowOverride) {

132

// Force override

133

this.forceOverrideService(serviceName, factory);

134

} else {

135

throw new Error(`Service '${serviceName}' already registered`);

136

}

137

}

138

}

139

}

140

}

141

```

142

143

### Scope-Related Errors

144

145

Handle errors related to scope lifecycle and management.

146

147

```javascript { .api }

148

/**

149

* Exception thrown when attempting to use a closed scope

150

*/

151

class ClosedScopeException extends Error {

152

/**

153

* Create exception for closed scope access

154

* @param scopeId - The ID of the closed scope

155

*/

156

constructor(scopeId: string);

157

158

/**

159

* ID of the scope that was closed

160

*/

161

scopeId: string;

162

}

163

164

/**

165

* Exception thrown when scope doesn't exist

166

*/

167

class ScopeNotCreatedException extends Error {

168

/**

169

* Create exception for non-existent scope

170

* @param scopeId - The ID of the missing scope

171

*/

172

constructor(scopeId: string);

173

174

/**

175

* ID of the scope that doesn't exist

176

*/

177

scopeId: string;

178

}

179

180

/**

181

* Exception thrown when scope already exists

182

*/

183

class ScopeAlreadyCreatedException extends Error {

184

/**

185

* Create exception for duplicate scope creation

186

* @param scopeId - The ID of the existing scope

187

*/

188

constructor(scopeId: string);

189

190

/**

191

* ID of the scope that already exists

192

*/

193

scopeId: string;

194

}

195

196

/**

197

* Exception thrown when scope definition is not found

198

*/

199

class NoScopeDefFoundException extends Error {

200

/**

201

* Create exception for missing scope definition

202

* @param message - Error description

203

*/

204

constructor(message: string);

205

206

/**

207

* The scope qualifier that was not found

208

*/

209

scopeQualifier?: Qualifier;

210

}

211

212

/**

213

* Exception thrown when scope value is missing

214

*/

215

class MissingScopeValueException extends Error {

216

/**

217

* Create exception for missing scope value

218

* @param message - Error description

219

*/

220

constructor(message: string);

221

}

222

```

223

224

**Usage Examples:**

225

226

```javascript

227

import {

228

GlobalContext,

229

ClosedScopeException,

230

ScopeNotCreatedException,

231

ScopeAlreadyCreatedException,

232

NoScopeDefFoundException,

233

named

234

} from "koin-core";

235

236

class ScopeManager {

237

constructor() {

238

this.activeScopes = new Map();

239

}

240

241

async createUserSession(userId) {

242

const scopeId = `session-${userId}`;

243

244

try {

245

const koin = GlobalContext.get();

246

const scope = koin.createScope(scopeId, named("session"));

247

248

this.activeScopes.set(userId, scope);

249

return scope;

250

251

} catch (error) {

252

if (error instanceof ScopeAlreadyCreatedException) {

253

console.warn(`Session scope for user ${userId} already exists`);

254

// Return existing scope

255

return koin.getScope(scopeId);

256

257

} else if (error instanceof NoScopeDefFoundException) {

258

console.error(`Session scope definition not found`);

259

console.error(`Missing scope qualifier: ${error.scopeQualifier?.value}`);

260

throw new Error("Session management not configured");

261

262

} else {

263

throw error;

264

}

265

}

266

}

267

268

async getUserSession(userId) {

269

const scopeId = `session-${userId}`;

270

271

try {

272

const koin = GlobalContext.get();

273

const scope = koin.getScope(scopeId);

274

275

// Try to get user session from scope

276

return scope.get(named("userSession"));

277

278

} catch (error) {

279

if (error instanceof ScopeNotCreatedException) {

280

console.error(`No session scope found for user ${userId}`);

281

// Create new session automatically

282

const newScope = await this.createUserSession(userId);

283

return newScope.get(named("userSession"));

284

285

} else if (error instanceof ClosedScopeException) {

286

console.error(`Session scope for user ${userId} is closed`);

287

// Remove from active scopes and recreate

288

this.activeScopes.delete(userId);

289

const newScope = await this.createUserSession(userId);

290

return newScope.get(named("userSession"));

291

292

} else {

293

throw error;

294

}

295

}

296

}

297

298

async closeUserSession(userId) {

299

const scope = this.activeScopes.get(userId);

300

301

if (scope) {

302

try {

303

scope.close();

304

this.activeScopes.delete(userId);

305

console.log(`Session closed for user ${userId}`);

306

307

} catch (error) {

308

if (error instanceof ClosedScopeException) {

309

// Already closed, just clean up

310

this.activeScopes.delete(userId);

311

} else {

312

throw error;

313

}

314

}

315

}

316

}

317

}

318

```

319

320

### Parameter and Property Errors

321

322

Handle errors related to parameter injection and property access.

323

324

```javascript { .api }

325

/**

326

* Exception thrown when required parameter is not found

327

*/

328

class NoParameterFoundException extends Error {

329

/**

330

* Create exception for missing parameter

331

* @param message - Error description

332

*/

333

constructor(message: string);

334

335

/**

336

* Parameter index that was requested

337

*/

338

parameterIndex?: number;

339

340

/**

341

* Parameter type that was requested

342

*/

343

parameterType?: any;

344

}

345

346

/**

347

* Exception thrown when parameter definition has errors

348

*/

349

class DefinitionParameterException extends Error {

350

/**

351

* Create exception for parameter definition error

352

* @param message - Error description

353

*/

354

constructor(message: string);

355

356

/**

357

* The definition that has parameter issues

358

*/

359

definition?: BeanDefinition<any>;

360

}

361

362

/**

363

* Exception thrown when property is not found

364

*/

365

class MissingPropertyException extends Error {

366

/**

367

* Create exception for missing property

368

* @param key - The property key that was not found

369

*/

370

constructor(key: string);

371

372

/**

373

* The property key that was missing

374

*/

375

key: string;

376

}

377

378

/**

379

* Exception thrown when property file is not found

380

*/

381

class NoPropertyFileFoundException extends Error {

382

/**

383

* Create exception for missing property file

384

* @param message - Error description

385

*/

386

constructor(message: string);

387

388

/**

389

* The property file path that was not found

390

*/

391

filePath?: string;

392

}

393

```

394

395

**Usage Examples:**

396

397

```javascript

398

import {

399

module,

400

parametersOf,

401

NoParameterFoundException,

402

DefinitionParameterException,

403

MissingPropertyException,

404

KoinComponent

405

} from "koin-core";

406

407

const dynamicModule = module((builder) => {

408

builder.factory((scope, params) => {

409

try {

410

// Validate required parameters

411

if (params.isEmpty()) {

412

throw new DefinitionParameterException("Database connection requires parameters");

413

}

414

415

const host = params.elementAt(0);

416

const port = params.elementAt(1);

417

418

if (!host || !port) {

419

throw new DefinitionParameterException("Host and port parameters required");

420

}

421

422

return new DatabaseConnection(host, port);

423

424

} catch (error) {

425

if (error instanceof NoParameterFoundException) {

426

console.error(`Parameter missing: index ${error.parameterIndex}, type ${error.parameterType?.name}`);

427

// Use default parameters

428

return new DatabaseConnection("localhost", 5432);

429

}

430

throw error;

431

}

432

});

433

});

434

435

class ConfigurableService extends KoinComponent {

436

constructor() {

437

super();

438

this.loadConfiguration();

439

}

440

441

loadConfiguration() {

442

try {

443

// Try to load configuration properties

444

this.apiUrl = this.getProperty("api.url");

445

this.timeout = this.getProperty("api.timeout", 5000);

446

this.retries = this.getProperty("api.retries", 3);

447

448

} catch (error) {

449

if (error instanceof MissingPropertyException) {

450

console.error(`Missing required property: ${error.key}`);

451

452

// Provide sensible defaults

453

switch (error.key) {

454

case "api.url":

455

this.apiUrl = "https://api.default.com";

456

break;

457

case "api.timeout":

458

this.timeout = 5000;

459

break;

460

case "api.retries":

461

this.retries = 3;

462

break;

463

default:

464

throw new Error(`Required configuration missing: ${error.key}`);

465

}

466

} else {

467

throw error;

468

}

469

}

470

}

471

472

async createConnection(host, port) {

473

try {

474

const connection = this.get(named("database"), () =>

475

parametersOf(host, port)

476

);

477

return connection;

478

479

} catch (error) {

480

if (error instanceof DefinitionParameterException) {

481

console.error(`Parameter error: ${error.message}`);

482

console.error(`Definition: ${error.definition?.qualifier?.value}`);

483

484

// Try with default parameters

485

const defaultConnection = this.get(named("database"), () =>

486

parametersOf("localhost", 5432)

487

);

488

return defaultConnection;

489

}

490

throw error;

491

}

492

}

493

}

494

```

495

496

### Application State Errors

497

498

Handle errors related to application lifecycle and state management.

499

500

```javascript { .api }

501

/**

502

* Exception thrown when Koin application is already started

503

*/

504

class KoinApplicationAlreadyStartedException extends Error {

505

/**

506

* Create exception for duplicate application start

507

* @param message - Error description

508

*/

509

constructor(message: string);

510

}

511

512

/**

513

* Exception thrown when trying to access Koin before it's started

514

*/

515

class IllegalStateException extends Error {

516

/**

517

* Create exception for illegal state access

518

* @param message - Error description

519

*/

520

constructor(message: string);

521

}

522

```

523

524

**Usage Examples:**

525

526

```javascript

527

import {

528

startKoin,

529

stopKoin,

530

GlobalContext,

531

KoinApplicationAlreadyStartedException,

532

IllegalStateException

533

} from "koin-core";

534

535

class ApplicationLifecycle {

536

constructor() {

537

this.isInitialized = false;

538

}

539

540

async start() {

541

try {

542

if (this.isInitialized) {

543

console.log("Application already initialized");

544

return;

545

}

546

547

startKoin((app) => {

548

app.modules([coreModule, apiModule]);

549

app.printLogger();

550

});

551

552

this.isInitialized = true;

553

console.log("Application started successfully");

554

555

} catch (error) {

556

if (error instanceof KoinApplicationAlreadyStartedException) {

557

console.warn("Koin application already started, skipping initialization");

558

this.isInitialized = true;

559

} else {

560

console.error("Failed to start application:", error.message);

561

throw error;

562

}

563

}

564

}

565

566

async stop() {

567

try {

568

if (!this.isInitialized) {

569

console.log("Application not initialized, nothing to stop");

570

return;

571

}

572

573

stopKoin();

574

this.isInitialized = false;

575

console.log("Application stopped successfully");

576

577

} catch (error) {

578

console.error("Error stopping application:", error.message);

579

// Force cleanup

580

this.isInitialized = false;

581

throw error;

582

}

583

}

584

585

getService(serviceName) {

586

try {

587

if (!this.isInitialized) {

588

throw new IllegalStateException("Application not initialized");

589

}

590

591

const koin = GlobalContext.get();

592

if (!koin) {

593

throw new IllegalStateException("Koin container not available");

594

}

595

596

return koin.get(named(serviceName));

597

598

} catch (error) {

599

if (error instanceof IllegalStateException) {

600

console.error(`Illegal state: ${error.message}`);

601

throw new Error("Service not available - application not ready");

602

}

603

throw error;

604

}

605

}

606

}

607

```

608

609

### Error Recovery and Fallback Strategies

610

611

Implement recovery strategies for robust error handling.

612

613

```javascript { .api }

614

/**

615

* Error recovery utility for dependency injection failures

616

*/

617

class DependencyRecovery {

618

static createFallbackStrategy(primaryFactory, fallbackFactory) {

619

return (scope, params) => {

620

try {

621

return primaryFactory(scope, params);

622

} catch (error) {

623

console.warn("Primary factory failed, using fallback:", error.message);

624

return fallbackFactory(scope, params);

625

}

626

};

627

}

628

629

static createRetryStrategy(factory, maxRetries = 3, delay = 1000) {

630

return async (scope, params) => {

631

for (let attempt = 1; attempt <= maxRetries; attempt++) {

632

try {

633

return await factory(scope, params);

634

} catch (error) {

635

if (attempt === maxRetries) {

636

throw error;

637

}

638

console.warn(`Attempt ${attempt} failed, retrying in ${delay}ms:`, error.message);

639

await new Promise(resolve => setTimeout(resolve, delay));

640

}

641

}

642

};

643

}

644

}

645

```

646

647

**Usage Examples:**

648

649

```javascript

650

import { module, DependencyRecovery } from "koin-core";

651

652

const resilientModule = module((builder) => {

653

// Service with fallback strategy

654

builder.single(

655

DependencyRecovery.createFallbackStrategy(

656

(scope, params) => new PrimaryDatabaseService(),

657

(scope, params) => new FallbackDatabaseService()

658

)

659

);

660

661

// Service with retry strategy

662

builder.factory(

663

DependencyRecovery.createRetryStrategy(

664

async (scope, params) => new ExternalApiClient(),

665

3, // max retries

666

2000 // delay between retries

667

)

668

);

669

});

670

```

671

672

## Types

673

674

```javascript { .api }

675

/** Base error types for Koin dependency injection */

676

677

/** Definition and resolution errors */

678

class NoDefinitionFoundException extends Error {

679

qualifier?: Qualifier;

680

type?: any;

681

}

682

683

class DefinitionOverrideException extends Error {

684

definition?: BeanDefinition<any>;

685

}

686

687

class InstanceCreationException extends Error {

688

cause?: Error;

689

definition?: BeanDefinition<any>;

690

}

691

692

/** Scope-related errors */

693

class ClosedScopeException extends Error {

694

scopeId: string;

695

}

696

697

class ScopeNotCreatedException extends Error {

698

scopeId: string;

699

}

700

701

class ScopeAlreadyCreatedException extends Error {

702

scopeId: string;

703

}

704

705

class NoScopeDefFoundException extends Error {

706

scopeQualifier?: Qualifier;

707

}

708

709

class MissingScopeValueException extends Error {}

710

711

/** Parameter and property errors */

712

class NoParameterFoundException extends Error {

713

parameterIndex?: number;

714

parameterType?: any;

715

}

716

717

class DefinitionParameterException extends Error {

718

definition?: BeanDefinition<any>;

719

}

720

721

class MissingPropertyException extends Error {

722

key: string;

723

}

724

725

class NoPropertyFileFoundException extends Error {

726

filePath?: string;

727

}

728

729

/** Application state errors */

730

class KoinApplicationAlreadyStartedException extends Error {}

731

732

class IllegalStateException extends Error {}

733

```