tryError Documentation
Utilities API
API reference for tryError utility functions and helpers
Type Guards
Type guard functions help TypeScript narrow types and provide runtime type checking for tryError results.
isTryError
Check if a value is a TryError instance with proper type narrowing.
1import { isTryError } from '@try-error/core';
2
3function isTryError<T = any>(value: unknown): value is TryError<T>
4
5// Usage examples
6const result = await tryAsync(() => fetchUser('123'));
7
8if (isTryError(result)) {
9 // TypeScript knows result is TryError
10 console.error('Error:', result.message);
11 console.error('Type:', result.type);
12 console.error('Context:', result.context);
13} else {
14 // TypeScript knows result is User
15 console.log('User:', result.name);
16}
17
18// Generic type checking
19function handleResult<T>(result: TryResult<T, TryError>) {
20 if (isTryError(result)) {
21 return { success: false, error: result };
22 }
23 return { success: true, data: result };
24}
isTrySuccess
Check if a TryResult represents a successful operation.
1import { isTrySuccess } from '@try-error/core';
2
3function isTrySuccess<T, E extends TryError>(
4 result: TryResult<T, E>
5): result is T
6
7// Usage examples
8const results = await Promise.all([
9 tryAsync(() => fetchUser('1')),
10 tryAsync(() => fetchUser('2')),
11 tryAsync(() => fetchUser('3'))
12]);
13
14const successfulResults = results.filter(isTrySuccess);
15// TypeScript knows successfulResults is User[]
16
17const users = results
18 .filter(isTrySuccess)
19 .map(user => user.name); // Type-safe access
20
21// Conditional processing
22function processResults<T>(results: TryResult<T, TryError>[]) {
23 const successful = results.filter(isTrySuccess);
24 const failed = results.filter(isTryError);
25
26 return {
27 successful,
28 failed,
29 successRate: successful.length / results.length
30 };
31}
hasErrorType
Check if an error has a specific type with type narrowing.
1import { hasErrorType } from '@try-error/core';
2
3function hasErrorType<T extends string>(
4 error: TryError,
5 type: T
6): error is TryError & { type: T }
7
8// Usage examples
9const result = await tryAsync(() => validateUser(userData));
10
11if (isTryError(result)) {
12 if (hasErrorType(result, 'ValidationError')) {
13 // Handle validation errors specifically
14 console.log('Validation failed:', result.context.field);
15 } else if (hasErrorType(result, 'NetworkError')) {
16 // Handle network errors
17 console.log('Network issue:', result.context.status);
18 } else {
19 // Handle other errors
20 console.log('Unknown error:', result.type);
21 }
22}
23
24// Multiple type checking
25function isRetryableError(error: TryError): boolean {
26 return hasErrorType(error, 'NetworkError') ||
27 hasErrorType(error, 'TimeoutError') ||
28 hasErrorType(error, 'RateLimitError');
29}
Result Transformers
Transform and manipulate tryError results with functional programming patterns.
mapResult
Transform successful results while preserving errors.
1import { mapResult } from '@try-error/core';
2
3function mapResult<T, U, E extends TryError>(
4 result: TryResult<T, E>,
5 transform: (value: T) => U
6): TryResult<U, E>
7
8// Usage examples
9const userResult = await tryAsync(() => fetchUser('123'));
10
11// Transform user to display name
12const nameResult = mapResult(userResult, user => user.name);
13
14// Chain transformations
15const upperNameResult = mapResult(nameResult, name => name.toUpperCase());
16
17// Complex transformations
18const userSummaryResult = mapResult(userResult, user => ({
19 id: user.id,
20 displayName: `${user.firstName} ${user.lastName}`,
21 isActive: user.status === 'active',
22 memberSince: new Date(user.createdAt).getFullYear()
23}));
24
25// Async transformations
26async function mapResultAsync<T, U, E extends TryError>(
27 result: TryResult<T, E>,
28 transform: (value: T) => Promise<U>
29): Promise<TryResult<U, E>> {
30 if (isTryError(result)) {
31 return result;
32 }
33 return tryAsync(() => transform(result));
34}
mapError
Transform errors while preserving successful results.
1import { mapError } from '@try-error/core';
2
3function mapError<T, E1 extends TryError, E2 extends TryError>(
4 result: TryResult<T, E1>,
5 transform: (error: E1) => E2
6): TryResult<T, E2>
7
8// Usage examples
9const result = await tryAsync(() => fetchUser('123'));
10
11// Transform network errors to user-friendly messages
12const friendlyResult = mapError(result, error => {
13 if (hasErrorType(error, 'NetworkError')) {
14 return createTryError(
15 'UserFriendlyError',
16 'Unable to load user data. Please try again.',
17 { originalError: error.type }
18 );
19 }
20 return error;
21});
22
23// Add context to errors
24const enrichedResult = mapError(result, error =>
25 enrichError(error, {
26 userId: '123',
27 timestamp: Date.now(),
28 userAgent: navigator.userAgent
29 })
30);
31
32// Convert errors to different types
33const apiResult = mapError(result, error => {
34 const statusCode = getHttpStatusForError(error);
35 return createTryError('ApiError', error.message, {
36 statusCode,
37 originalType: error.type,
38 context: error.context
39 });
40});
flatMapResult
Chain operations that return TryResult, flattening nested results.
1import { flatMapResult } from '@try-error/core';
2
3function flatMapResult<T, U, E extends TryError>(
4 result: TryResult<T, E>,
5 transform: (value: T) => TryResult<U, E>
6): TryResult<U, E>
7
8// Usage examples
9const userResult = await tryAsync(() => fetchUser('123'));
10
11// Chain dependent operations
12const profileResult = flatMapResult(userResult, user =>
13 tryAsync(() => fetchUserProfile(user.id))
14);
15
16// Multiple chained operations
17const fullUserData = await tryAsync(() => fetchUser('123'))
18 .then(result => flatMapResult(result, user =>
19 tryAsync(() => fetchUserProfile(user.id))
20 ))
21 .then(result => flatMapResult(result, profile =>
22 tryAsync(() => fetchUserPreferences(profile.userId))
23 ));
24
25// Conditional chaining
26const conditionalResult = flatMapResult(userResult, user => {
27 if (user.isActive) {
28 return tryAsync(() => fetchActiveUserData(user.id));
29 } else {
30 return tryAsync(() => fetchInactiveUserData(user.id));
31 }
32});
33
34// Error propagation in chains
35async function processUserWorkflow(userId: string) {
36 return tryAsync(() => fetchUser(userId))
37 .then(result => flatMapResult(result, user =>
38 tryAsync(() => validateUser(user))
39 ))
40 .then(result => flatMapResult(result, user =>
41 tryAsync(() => processUser(user))
42 ))
43 .then(result => flatMapResult(result, processed =>
44 tryAsync(() => saveProcessedUser(processed))
45 ));
46}
Result Combinators
Combine multiple tryError results with various strategies.
combineResults
Combine multiple results into a single result containing all successful values.
1import { combineResults } from '@try-error/core';
2
3function combineResults<T extends readonly TryResult<any, any>[]>(
4 results: T
5): TryResult<UnwrapResults<T>, TryError>
6
7// Usage examples
8const userResult = await tryAsync(() => fetchUser('123'));
9const profileResult = await tryAsync(() => fetchProfile('123'));
10const prefsResult = await tryAsync(() => fetchPreferences('123'));
11
12// Combine all results
13const combinedResult = combineResults([userResult, profileResult, prefsResult]);
14
15if (isTrySuccess(combinedResult)) {
16 const [user, profile, preferences] = combinedResult;
17 // All operations succeeded
18 console.log('User data loaded:', { user, profile, preferences });
19} else {
20 // At least one operation failed
21 console.error('Failed to load complete user data:', combinedResult.message);
22}
23
24// Named combination
25const namedResult = combineResults({
26 user: userResult,
27 profile: profileResult,
28 preferences: prefsResult
29});
30
31if (isTrySuccess(namedResult)) {
32 const { user, profile, preferences } = namedResult;
33 // Type-safe destructuring
34}
35
36// Partial success handling
37function combineWithPartialSuccess<T extends Record<string, TryResult<any, any>>>(
38 results: T
39): { successful: Partial<UnwrapResults<T>>; failed: TryError[] } {
40 const successful: any = {};
41 const failed: TryError[] = [];
42
43 for (const [key, result] of Object.entries(results)) {
44 if (isTrySuccess(result)) {
45 successful[key] = result;
46 } else {
47 failed.push(result);
48 }
49 }
50
51 return { successful, failed };
52}
raceResults
Return the first successful result or all errors if all fail.
1import { raceResults } from '@try-error/core';
2
3function raceResults<T>(
4 results: Promise<TryResult<T, TryError>>[]
5): Promise<TryResult<T, TryError[]>>
6
7// Usage examples
8const primaryResult = tryAsync(() => fetchFromPrimaryAPI('123'));
9const fallbackResult = tryAsync(() => fetchFromFallbackAPI('123'));
10const cacheResult = tryAsync(() => fetchFromCache('123'));
11
12// Race for first success
13const fastestResult = await raceResults([
14 primaryResult,
15 fallbackResult,
16 cacheResult
17]);
18
19if (isTrySuccess(fastestResult)) {
20 console.log('Got data from fastest source:', fastestResult);
21} else {
22 console.error('All sources failed:', fastestResult);
23}
24
25// Timeout with fallback
26async function fetchWithTimeout<T>(
27 operation: () => Promise<T>,
28 timeoutMs: number,
29 fallback: () => Promise<T>
30): Promise<TryResult<T, TryError>> {
31 const timeoutPromise = new Promise<TryResult<T, TryError>>(resolve => {
32 setTimeout(() => {
33 resolve(createTryError('TimeoutError', `Operation timed out after ${timeoutMs}ms`));
34 }, timeoutMs);
35 });
36
37 return raceResults([
38 tryAsync(operation),
39 timeoutPromise,
40 tryAsync(fallback)
41 ]);
42}
sequenceResults
Execute operations in sequence, stopping at the first error.
1import { sequenceResults } from '@try-error/core';
2
3function sequenceResults<T>(
4 operations: (() => Promise<TryResult<T, TryError>>)[]
5): Promise<TryResult<T[], TryError>>
6
7// Usage examples
8const operations = [
9 () => tryAsync(() => validateInput(data)),
10 () => tryAsync(() => processData(data)),
11 () => tryAsync(() => saveData(data)),
12 () => tryAsync(() => notifySuccess(data))
13];
14
15const sequenceResult = await sequenceResults(operations);
16
17if (isTrySuccess(sequenceResult)) {
18 console.log('All operations completed:', sequenceResult);
19} else {
20 console.error('Sequence failed at step:', sequenceResult);
21}
22
23// Pipeline with transformations
24async function processPipeline<T>(
25 input: T,
26 steps: ((input: any) => Promise<TryResult<any, TryError>>)[]
27): Promise<TryResult<any, TryError>> {
28 let current: TryResult<any, TryError> = input;
29
30 for (const step of steps) {
31 if (isTryError(current)) {
32 return current;
33 }
34 current = await step(current);
35 }
36
37 return current;
38}
39
40// Usage
41const pipelineResult = await processPipeline(userData, [
42 data => tryAsync(() => validateUser(data)),
43 data => tryAsync(() => enrichUserData(data)),
44 data => tryAsync(() => saveUser(data)),
45 data => tryAsync(() => sendWelcomeEmail(data))
46]);
Utility Helpers
Additional helper functions for common tryError patterns and operations.
unwrapOr
Extract the value from a result or return a default value.
1import { unwrapOr } from '@try-error/core';
2
3function unwrapOr<T>(result: TryResult<T, TryError>, defaultValue: T): T
4
5// Usage examples
6const userResult = await tryAsync(() => fetchUser('123'));
7
8// Simple default
9const user = unwrapOr(userResult, { id: '123', name: 'Unknown User' });
10
11// Computed default
12const userName = unwrapOr(
13 mapResult(userResult, u => u.name),
14 'Anonymous'
15);
16
17// Function-based default
18function unwrapOrElse<T>(
19 result: TryResult<T, TryError>,
20 getDefault: (error: TryError) => T
21): T {
22 if (isTrySuccess(result)) {
23 return result;
24 }
25 return getDefault(result);
26}
27
28const userWithFallback = unwrapOrElse(userResult, error => {
29 console.warn('Failed to fetch user:', error.message);
30 return createGuestUser();
31});
32
33// Nullable unwrap
34function unwrapOrNull<T>(result: TryResult<T, TryError>): T | null {
35 return isTrySuccess(result) ? result : null;
36}
37
38const maybeUser = unwrapOrNull(userResult);
39if (maybeUser) {
40 console.log('User found:', maybeUser.name);
41}
retry
Retry operations with configurable strategies and backoff.
1import { retry, RetryOptions } from '@try-error/core';
2
3interface RetryOptions {
4 maxAttempts: number;
5 delay?: number;
6 backoff?: 'linear' | 'exponential';
7 shouldRetry?: (error: TryError) => boolean;
8}
9
10function retry<T>(
11 operation: () => Promise<T>,
12 options: RetryOptions
13): Promise<TryResult<T, TryError>>
14
15// Usage examples
16const result = await retry(
17 () => fetchUser('123'),
18 {
19 maxAttempts: 3,
20 delay: 1000,
21 backoff: 'exponential'
22 }
23);
24
25// Custom retry logic
26const customRetryResult = await retry(
27 () => processPayment(paymentData),
28 {
29 maxAttempts: 5,
30 delay: 500,
31 shouldRetry: (error) => {
32 // Only retry on network errors or rate limits
33 return hasErrorType(error, 'NetworkError') ||
34 hasErrorType(error, 'RateLimitError');
35 }
36 }
37);
38
39// Retry with jitter
40async function retryWithJitter<T>(
41 operation: () => Promise<T>,
42 options: RetryOptions & { jitter?: boolean }
43): Promise<TryResult<T, TryError>> {
44 let lastError: TryError;
45
46 for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
47 const result = await tryAsync(operation);
48
49 if (isTrySuccess(result)) {
50 return result;
51 }
52
53 lastError = result;
54
55 if (attempt < options.maxAttempts &&
56 (!options.shouldRetry || options.shouldRetry(result))) {
57 const delay = calculateDelay(attempt, options);
58 const jitteredDelay = options.jitter ?
59 delay * (0.5 + Math.random() * 0.5) : delay;
60 await sleep(jitteredDelay);
61 }
62 }
63
64 return lastError!;
65}
timeout
Add timeout functionality to async operations.
1import { timeout } from '@try-error/core';
2
3function timeout<T>(
4 operation: () => Promise<T>,
5 timeoutMs: number,
6 timeoutMessage?: string
7): Promise<TryResult<T, TryError>>
8
9// Usage examples
10const result = await timeout(
11 () => fetchLargeDataset(),
12 5000, // 5 second timeout
13 'Data fetch timed out'
14);
15
16// Timeout with cleanup
17async function timeoutWithCleanup<T>(
18 operation: (signal: AbortSignal) => Promise<T>,
19 timeoutMs: number
20): Promise<TryResult<T, TryError>> {
21 const controller = new AbortController();
22
23 const timeoutId = setTimeout(() => {
24 controller.abort();
25 }, timeoutMs);
26
27 try {
28 const result = await tryAsync(() => operation(controller.signal));
29 clearTimeout(timeoutId);
30 return result;
31 } catch (error) {
32 clearTimeout(timeoutId);
33 if (controller.signal.aborted) {
34 return createTryError('TimeoutError', `Operation timed out after ${timeoutMs}ms`);
35 }
36 throw error;
37 }
38}
39
40// Progressive timeout
41async function progressiveTimeout<T>(
42 operation: () => Promise<T>,
43 timeouts: number[]
44): Promise<TryResult<T, TryError>> {
45 for (const timeoutMs of timeouts) {
46 const result = await timeout(operation, timeoutMs);
47 if (isTrySuccess(result)) {
48 return result;
49 }
50
51 // If it's not a timeout error, don't retry
52 if (!hasErrorType(result, 'TimeoutError')) {
53 return result;
54 }
55 }
56
57 return createTryError(
58 'TimeoutError',
59 `Operation failed after all timeout attempts: ${timeouts.join(', ')}ms`
60 );
61}
Best Practices
✅ Do
- • Use type guards for proper type narrowing
- • Combine results when you need all operations to succeed
- • Use mapResult for transforming successful values
- • Use flatMapResult for chaining dependent operations
- • Implement retry logic for transient failures
- • Add timeouts to prevent hanging operations
❌ Don't
- • Ignore type guards and manually check error properties
- • Use unwrapOr with expensive default value computations
- • Retry operations that will never succeed
- • Set overly aggressive timeouts for normal operations
- • Chain too many operations without error handling
- • Use combinators when simple sequential logic is clearer
Related Pages
Performance Optimization
Utilities for optimizing tryError performance in high-throughput scenarios.
Object Pooling
Manage error object pools to reduce garbage collection pressure.
1import {
2 ErrorPool,
3 getGlobalErrorPool,
4 configureErrorPool,
5 resetErrorPool,
6 getErrorPoolStats
7} from '@try-error/core';
8
9// Create a custom pool
10const pool = new ErrorPool(100); // Pool size
11
12// Acquire and release errors
13const error = pool.acquire();
14error.type = 'CustomError';
15error.message = 'Something went wrong';
16// ... use the error
17pool.release(error); // Return to pool
18
19// Configure global pool
20configureErrorPool({
21 enabled: true,
22 maxSize: 200
23});
24
25// Get pool statistics
26const stats = getErrorPoolStats();
27console.log({
28 poolSize: stats.poolSize,
29 activeCount: stats.activeCount,
30 hitRate: stats.hitRate,
31 hits: stats.hits,
32 misses: stats.misses
33});
34
35// Reset global pool
36resetErrorPool();
37
38// Pool management methods
39pool.clear(); // Empty the pool
40pool.resize(50); // Change pool size
41const stats = pool.getStats(); // Get pool statistics
Lazy Evaluation
Create errors with lazy-evaluated properties for better performance.
1import {
2 createLazyError,
3 makeLazy,
4 isLazyProperty,
5 forceLazyEvaluation,
6 createDebugProxy
7} from '@try-error/core';
8
9// Create error with lazy properties
10const error = createLazyError({
11 type: 'LazyError',
12 message: 'Error message',
13 getSource: () => {
14 // Expensive computation only when accessed
15 return computeSourceLocation();
16 },
17 getStack: () => {
18 // Generate stack trace on demand
19 return new Error().stack;
20 },
21 getTimestamp: () => Date.now(),
22 context: { immediate: 'value' }
23});
24
25// Make existing error lazy
26const lazyError = makeLazy(existingError, {
27 source: () => computeSource(),
28 stack: () => generateStack(),
29 context: () => gatherContext()
30});
31
32// Check if property is lazy
33if (isLazyProperty(error, 'stack')) {
34 console.log('Stack will be computed on access');
35}
36
37// Force all lazy properties to evaluate
38const evaluated = forceLazyEvaluation(error);
39
40// Debug lazy property access
41const debugError = createDebugProxy(error);
42// Logs: "Lazy evaluation triggered for property: stack"
43console.log(debugError.stack);
Configuration Presets
Pre-configured settings for different performance scenarios.
1import { configure, ConfigPresets } from '@try-error/core';
2
3// Maximum performance - minimal features
4configure(ConfigPresets.minimal());
5// Enables: minimalErrors, skipTimestamp, skipContext, skipSourceLocation
6// Disables: stack traces, context capture, source location
7
8// Production - balanced performance and debugging
9configure(ConfigPresets.production());
10// Enables: lazy evaluation, object pooling
11// Disables: verbose logging, debug features
12
13// Development - full debugging features
14configure(ConfigPresets.development());
15// Enables: all debugging features, verbose logging
16// Disables: performance optimizations
17
18// Custom performance configuration
19configure({
20 performance: {
21 errorCreation: {
22 objectPooling: true,
23 poolSize: 100,
24 lazyStackTrace: true,
25 lazySourceLocation: true
26 },
27 contextCapture: {
28 maxDepth: 3,
29 maxProperties: 50,
30 excludePatterns: ['password', 'token']
31 },
32 memoryManagement: {
33 maxErrorsInMemory: 1000,
34 errorTTL: 60000 // 1 minute
35 }
36 }
37});
Middleware System
Extend tryError with custom logic using middleware pipelines.
MiddlewarePipeline
Create and manage middleware pipelines for error handling.
1import { MiddlewarePipeline, ErrorMiddleware } from '@try-error/core';
2
3// Create a pipeline
4const pipeline = new MiddlewarePipeline();
5
6// Add middleware
7pipeline
8 .use((result, next) => {
9 console.log('Before:', result);
10 const nextResult = next();
11 console.log('After:', nextResult);
12 return nextResult;
13 })
14 .use(loggingMiddleware)
15 .use(retryMiddleware(3));
16
17// Execute pipeline
18const result = pipeline.execute(trySync(() => operation()));
19
20// Wrap a function
21const safeFn = pipeline.wrap((x: number) =>
22 trySync(() => riskyOperation(x))
23);
24
25// Clone pipeline
26const cloned = pipeline.clone();
27
28// Pipeline properties
29console.log(pipeline.length); // Number of middleware
Built-in Middleware
Common middleware implementations ready to use.
1import {
2 loggingMiddleware,
3 retryMiddleware,
4 transformMiddleware,
5 enrichContextMiddleware,
6 circuitBreakerMiddleware,
7 rateLimitMiddleware,
8 filterMiddleware,
9 compose
10} from '@try-error/core';
11
12// Logging
13pipeline.use(loggingMiddleware(console.error));
14pipeline.use(loggingMiddleware(customLogger));
15
16// Retry with predicate
17pipeline.use(retryMiddleware(3, error =>
18 error.type === 'NetworkError'
19));
20
21// Transform errors
22pipeline.use(transformMiddleware(error => ({
23 ...error,
24 message: sanitize(error.message)
25})));
26
27// Enrich context
28pipeline.use(enrichContextMiddleware(() => ({
29 requestId: getCurrentRequestId(),
30 timestamp: Date.now()
31})));
32
33// Circuit breaker
34pipeline.use(circuitBreakerMiddleware({
35 threshold: 5,
36 timeout: 60000,
37 onOpen: () => console.warn('Circuit opened'),
38 onClose: () => console.info('Circuit closed')
39}));
40
41// Rate limiting
42pipeline.use(rateLimitMiddleware(1000, 100)); // 100/sec
43
44// Filter by error type
45pipeline.use(filterMiddleware(
46 ['NetworkError', 'TimeoutError'],
47 retryMiddleware(5)
48));
49
50// Compose multiple middleware
51const errorHandling = compose(
52 loggingMiddleware(logger),
53 retryMiddleware(3),
54 transformMiddleware(sanitize)
55);
Global Registry
Register and manage named middleware pipelines globally.
1import { globalRegistry } from '@try-error/core';
2
3// Create named pipelines
4const apiPipeline = new MiddlewarePipeline()
5 .use(rateLimitMiddleware(1000, 100))
6 .use(retryMiddleware(3))
7 .use(loggingMiddleware);
8
9const dbPipeline = new MiddlewarePipeline()
10 .use(circuitBreakerMiddleware({ threshold: 5 }))
11 .use(transformMiddleware);
12
13// Register pipelines
14globalRegistry.register('api', apiPipeline);
15globalRegistry.register('database', dbPipeline);
16
17// Retrieve pipelines
18const api = globalRegistry.get('api');
19const db = globalRegistry.get('database');
20
21// List registered pipelines
22const names = globalRegistry.list(); // ['api', 'database']
23
24// Remove pipeline
25globalRegistry.remove('api'); // returns boolean
Plugin System
Extend tryError with plugins that add new capabilities and integrations.
Plugin Manager
Install, enable, and manage plugins for tryError.
1import { pluginManager, Plugin } from '@try-error/core';
2
3// Install a plugin
4await pluginManager.install(myPlugin);
5
6// Enable/disable plugins
7await pluginManager.enable('plugin-name');
8await pluginManager.disable('plugin-name');
9
10// Uninstall plugin
11await pluginManager.uninstall('plugin-name');
12
13// Check plugin status
14const isInstalled = pluginManager.isInstalled('plugin-name');
15const isEnabled = pluginManager.isEnabled('plugin-name');
16
17// Get plugin information
18const plugin = pluginManager.get('plugin-name');
19const installed = pluginManager.getInstalled();
20const enabled = pluginManager.getEnabled();
21
22// Get merged configuration from all plugins
23const config = pluginManager.getMergedConfig();
24
25// Get all middleware from plugins
26const middleware = pluginManager.getAllMiddleware();
27
28// Get custom error types from plugins
29const errorTypes = pluginManager.getAllErrorTypes();
30
31// Get utilities from plugins
32const utilities = pluginManager.getAllUtilities();
33
34// Notify plugins of config changes
35await pluginManager.notifyConfigChange(newConfig);
Creating Plugins
Build custom plugins to extend tryError functionality.
1import { createPlugin, Plugin, PluginAPI } from '@try-error/core';
2
3// Using createPlugin helper
4const myPlugin = createPlugin(
5 {
6 name: 'my-plugin',
7 version: '1.0.0',
8 description: 'My custom plugin',
9 dependencies: ['other-plugin']
10 },
11 (api: PluginAPI) => ({
12 // Add middleware
13 middleware: api.addMiddleware(
14 loggingMiddleware,
15 retryMiddleware
16 ),
17
18 // Create error types
19 errorTypes: {
20 ...api.createErrorType('CustomError', (message, context) => ({
21 [TRY_ERROR_BRAND]: true,
22 type: 'CustomError',
23 message,
24 source: 'my-plugin',
25 timestamp: Date.now(),
26 context
27 }))
28 },
29
30 // Add utilities
31 utilities: {
32 ...api.addUtility('myHelper', helperFunction)
33 }
34 })
35);
36
37// Manual plugin creation
38const plugin: Plugin = {
39 metadata: {
40 name: 'manual-plugin',
41 version: '1.0.0'
42 },
43
44 hooks: {
45 onInstall: async () => console.log('Installing'),
46 onUninstall: async () => console.log('Uninstalling'),
47 onEnable: async () => console.log('Enabling'),
48 onDisable: async () => console.log('Disabling'),
49 onConfigChange: async (config) => console.log('Config:', config)
50 },
51
52 capabilities: {
53 config: { customOption: true },
54 middleware: [customMiddleware],
55 errorTypes: { CustomError: customErrorFactory },
56 utilities: { helper: helperFunction }
57 }
58};