# Troubleshooting

## 🔧 Troubleshooting

### Common Issues

#### Type Errors with Models

```typescript
// ❌ Incorrect - generic types not specified
const builder = repository.model('user');

// ✅ Correct - with proper typing
const builder = repository.model<User>('user') as PrismaUnifiedBuilder<...>;

// ✅ Better - use typed accessors
const builder = repository.user; // Fully typed automatically
```

#### Transaction Errors

```typescript
// ❌ Incorrect - trying to use original builder inside transaction
await repository.user.Transaction(async (tx) => {
    return await repository.user.Create({ name: 'Test' }); // Wrong!
});

// ✅ Correct - use transaction builder
await repository.user.Transaction(async (txBuilder) => {
    return await txBuilder.Create({ name: 'Test' }); // Correct!
});
```

#### Performance Issues

```typescript
// ❌ Inefficient - synchronous processing of large dataset
const results = largeDataset
    .Where((x) => heavyComputation(x))
    .Select((x) => transform(x))
    .ToArray();

// ✅ Efficient - asynchronous processing
const results = await AsyncEnumerable.from(largeDataset)
    .Where(async (x) => await heavyComputationAsync(x))
    .Select(async (x) => await transformAsync(x))
    .ToArrayAsync();
```

#### GraphQL Configuration Issues

```typescript
// ❌ Incorrect - missing GraphQL client configuration
@Module({
    imports: [
        PrismaCoreModule.forRoot({
            // Missing graphqlClientProvider
        }),
    ],
})
export class AppModule {}

// ✅ Correct - proper GraphQL client setup
const GRAPHQL_CLIENT_PROVIDER = {
    provide: 'GRAPHQL_CLIENT',
    useFactory: () =>
        createClient({
            url: 'http://localhost:4000/graphql',
        }),
};

@Module({
    imports: [
        PrismaCoreModule.forRoot({
            graphqlClientProvider: GRAPHQL_CLIENT_PROVIDER,
        }),
    ],
})
export class AppModule {}
```

#### Repository Access Errors

```typescript
// ❌ Incorrect - accessing undefined model
const results = await repository.nonExistentModel.ToArray(); // Runtime error

// ✅ Correct - check available models first
const availableModels = repository.getModelNames();
console.log('Available models:', availableModels);

if (availableModels.includes('user')) {
    const results = await repository.user.ToArray();
}

// Or use dynamic access with error handling
try {
    const builder = repository.model('user');
    const results = await builder.ToArray();
} catch (error) {
    console.error('Model not found:', error);
}
```

### Debug Mode

Enable detailed logging for troubleshooting:

```typescript
// Environment variable
process.env.PRISMA_CORE_DEBUG = 'true';

// Or programmatically
import { PrismaCoreService } from '@algochad/prisma-core';

const service = new PrismaCoreService(prismaClient, {
    debug: true,
    logQueries: true,
    logPerformance: true,
});
```

### Common Error Messages and Solutions

#### "Model not found" Error

**Error**: `Error: Model 'modelName' not found in Prisma schema`

**Solution**:

1. Verify the model exists in your `schema.prisma`
2. Run `npx prisma generate` to update the client
3. Check model name spelling and case sensitivity
4. Ensure the Prisma client is properly configured

#### "Transaction failed" Error

**Error**: `Error: Transaction failed: Cannot use repository instance inside transaction`

**Solution**:

```typescript
// Use the transaction builder parameter, not the original repository
await repository.user.Transaction(async (txBuilder) => {
    // Use txBuilder, not repository.user
    return await txBuilder.Create({ name: 'Test' });
});
```

#### "GraphQL client not configured" Error

**Error**: `Error: GraphQL client not provided in module configuration`

**Solution**:

```typescript
// Ensure GraphQL client is provided
const GRAPHQL_CLIENT_PROVIDER = {
    provide: 'GRAPHQL_CLIENT',
    useFactory: () => createClient({ url: 'your-graphql-endpoint' }),
};

PrismaCoreModule.forRoot({
    graphqlClientProvider: GRAPHQL_CLIENT_PROVIDER,
});
```

#### Memory Issues with Large Datasets

**Error**: `JavaScript heap out of memory`

**Solution**:

```typescript
// Use AsyncEnumerable for large datasets
const results = await AsyncEnumerable.from(largeDataset)
    .Where(async (item) => await processItemAsync(item))
    .ToArrayAsync();

// Or process in chunks
const chunkSize = 1000;
for (let i = 0; i < largeDataset.length; i += chunkSize) {
    const chunk = largeDataset.slice(i, i + chunkSize);
    await processChunk(chunk);
}
```

### Performance Troubleshooting

#### Slow Query Performance

**Issue**: Queries taking too long to execute

**Solutions**:

1. Use `AsQueryable()` for database-level operations
2. Switch to `AsyncEnumerable` for complex transformations
3. Add proper database indexes
4. Use `Select()` to limit returned fields

```typescript
// Better: Database-level filtering and selection
const results = await repository.user
    .AsQueryable()
    .Where({ isActive: true })
    .Select({ id: true, name: true, email: true })
    .Take(100)
    .ToArrayAsync();

// Instead of: In-memory processing of all records
const allUsers = await repository.user.ToArray();
const filtered = allUsers.filter((u) => u.isActive).slice(0, 100);
```

#### Memory Usage Issues

**Issue**: High memory consumption

**Solutions**:

1. Use pagination with `Skip()` and `Take()`
2. Process data in streams with `AsyncEnumerable`
3. Clear repository cache when needed

```typescript
// Process in pages
const pageSize = 1000;
let page = 0;
let hasMore = true;

while (hasMore) {
    const results = await repository.user
        .Skip(page * pageSize)
        .Take(pageSize)
        .ToArray();

    hasMore = results.length === pageSize;
    await processResults(results);
    page++;
}

// Clear cache periodically
repository.clearCache();
```

### Development Tips

#### Debugging Query Generation

```typescript
// Enable query logging in development
const service = new PrismaCoreService(prismaClient, {
    debug: process.env.NODE_ENV === 'development',
    logQueries: true,
});
```

#### Type Safety Issues

```typescript
// Use proper typing for models
interface TypedRepository extends PrismaRepository {
    readonly user: PrismaUnifiedBuilder<User>;
    readonly post: PrismaUnifiedBuilder<Post>;
}

// Cast your repository for better type safety
const typedRepo = repository as TypedRepository;
```

#### Testing Configurations

```typescript
// Use in-memory database for testing
const testPrismaClient = new PrismaClient({
    datasources: {
        db: {
            url: 'file:./test.db',
        },
    },
});

// Clear test data between tests
afterEach(async () => {
    await testPrismaClient.$executeRaw`DELETE FROM User`;
    await testPrismaClient.$executeRaw`DELETE FROM Post`;
});
```

## Getting Help

If you're still experiencing issues:

1. Check the [GitHub Issues](https://github.com/algochad/prisma-core/issues) for similar problems
2. Review the [examples and tutorials](./examples.md) for working code samples
3. Enable debug mode to get more detailed error information
4. Create a minimal reproduction case when reporting bugs

## Next Steps

- [See examples and tutorials](./examples.md)
- [Learn about contributing](./contributing.md)
- [Review the license](./LICENSE.md)
