What problem does it solve? Durable functions often need cross-cutting concerns like logging, error tracking, encryption, and shared clients applied uniformly, and writing this logic inside every function leads to duplication and inconsistency. ## Core Features & Use Cases - Custom Middleware Lifecycle: Build middleware with the v4 InngestMiddleware API using hooks like onFunctionRun, onSendEvent, transformInput, and transformOutput. - Dependency Injection: Inject shared clients such as databases, Stripe, or OpenAI into function handlers using the built-in dependencyInjectionMiddleware or custom patterns. - Official Middleware Packages: Apply @inngest/middleware-encryption for payload encryption with key rotation and @inngest/middleware-sentry for error tracking and tracing. - Use Case: You want every function run to report exceptions to Sentry with function ID and event name context, while encrypting sensitive step data and injecting a Prisma client into all handlers. ## Quick Start Add Sentry error tracking and dependency injection middleware to my Inngest client so all functions share a database client and report errors automatically.