@algochad/prisma-core
Version:
A comprehensive NestJS library that provides EF-Core-like operations using Prisma and GraphQL. Features LINQ-style query builders, advanced data manipulation, GraphQL integration with genql, and a unified API for both Prisma and GraphQL operations. Includ
304 lines (229 loc) • 7.32 kB
Markdown
# 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)