feat(devx): P3.3-A/B/C Developer experience improvements

P3.3-A: Enhanced error messages with actionable guidance
- Added ERROR_GUIDANCE constant with messages, guidance, and platform hints
- Added NOT_SUPPORTED error code
- Updated web.ts to use DailyNotificationError instead of plain Error

P3.3-B: Debug helpers
- Added getDebugState() method to web.ts (throws NOT_SUPPORTED for web)

P3.3-C: Type tightening
- Enhanced ScheduleWithStatus with status field ('active' | 'paused' | 'error')

Verification:
- TypeScript compiles 
- No breaking changes 
- Error messages now include actionable guidance 
This commit is contained in:
Matthew Raymer
2025-12-23 07:17:46 +00:00
parent 0b01032b5b
commit 1a1a94c995
3 changed files with 160 additions and 5 deletions

View File

@@ -51,6 +51,8 @@ export interface Schedule {
export interface ScheduleWithStatus extends Schedule {
/** Whether the alarm is actually scheduled in AlarmManager (Android only, for 'notify' schedules) */
isActuallyScheduled: boolean;
/** Status of the schedule */
status: 'active' | 'paused' | 'error';
}
/**

View File

@@ -50,8 +50,131 @@ export enum ErrorCode {
PLUGIN_NOT_INITIALIZED = 'plugin_not_initialized',
INTERNAL_ERROR = 'internal_error',
SYSTEM_ERROR = 'system_error',
// Platform Errors
NOT_SUPPORTED = 'not_supported',
}
/**
* Error code metadata with actionable guidance
*
* Provides human-readable messages and actionable guidance for each error code.
* Platform-specific hints help developers resolve issues quickly.
*/
export const ERROR_GUIDANCE: Record<ErrorCode, {
message: string;
guidance: string;
platformHints?: Record<string, string>
}> = {
[ErrorCode.NOTIFICATIONS_DENIED]: {
message: 'Notification permission denied',
guidance: 'Request permission using requestPermission() before scheduling notifications',
platformHints: {
ios: 'Check Info.plist for notification permission description',
android: 'Check AndroidManifest.xml for POST_NOTIFICATIONS permission'
}
},
[ErrorCode.BACKGROUND_REFRESH_DISABLED]: {
message: 'Background refresh is disabled',
guidance: 'Enable background app refresh in device settings',
platformHints: {
ios: 'Settings > General > Background App Refresh',
android: 'Settings > Apps > Battery optimization'
}
},
[ErrorCode.PERMISSION_DENIED]: {
message: 'Permission denied',
guidance: 'Request permission before performing this operation'
},
[ErrorCode.NOTIFICATION_PERMISSION_DENIED]: {
message: 'Notification permission denied',
guidance: 'Request notification permission using requestPermission()'
},
[ErrorCode.INVALID_TIME_FORMAT]: {
message: 'Invalid time format',
guidance: 'Use HH:mm format (e.g., "09:30" for 9:30 AM)'
},
[ErrorCode.INVALID_TIME_VALUES]: {
message: 'Invalid time values',
guidance: 'Ensure hours are 0-23 and minutes are 0-59'
},
[ErrorCode.CONFIGURATION_FAILED]: {
message: 'Configuration failed',
guidance: 'Check configuration parameters and platform-specific requirements'
},
[ErrorCode.MISSING_REQUIRED_PARAMETER]: {
message: 'Missing required parameter',
guidance: 'Provide all required parameters for this operation'
},
[ErrorCode.SCHEDULING_FAILED]: {
message: 'Scheduling failed',
guidance: 'Check schedule parameters and platform permissions'
},
[ErrorCode.TASK_SCHEDULING_FAILED]: {
message: 'Background task scheduling failed',
guidance: 'Ensure background tasks are properly registered and permissions granted'
},
[ErrorCode.NOTIFICATION_SCHEDULING_FAILED]: {
message: 'Notification scheduling failed',
guidance: 'Check notification permissions and platform limits'
},
[ErrorCode.PENDING_NOTIFICATION_LIMIT_EXCEEDED]: {
message: 'Pending notification limit exceeded',
guidance: 'Reduce number of scheduled notifications or clear old ones'
},
[ErrorCode.STORAGE_ERROR]: {
message: 'Storage error',
guidance: 'Check storage permissions and available space'
},
[ErrorCode.DATABASE_ERROR]: {
message: 'Database error',
guidance: 'Check database integrity and migration status'
},
[ErrorCode.NETWORK_ERROR]: {
message: 'Network error',
guidance: 'Check network connectivity and retry'
},
[ErrorCode.FETCH_FAILED]: {
message: 'Fetch operation failed',
guidance: 'Check network connectivity and API endpoint availability'
},
[ErrorCode.TIMEOUT]: {
message: 'Operation timed out',
guidance: 'Retry operation or increase timeout value'
},
[ErrorCode.BG_TASK_NOT_REGISTERED]: {
message: 'Background task not registered',
guidance: 'Register background task using registerBackgroundTask()',
platformHints: {
ios: 'Register BGTaskScheduler tasks in AppDelegate',
android: 'Register WorkManager tasks in Application class'
}
},
[ErrorCode.BG_TASK_EXECUTION_FAILED]: {
message: 'Background task execution failed',
guidance: 'Check background task implementation and platform constraints'
},
[ErrorCode.PLUGIN_NOT_INITIALIZED]: {
message: 'Plugin not initialized',
guidance: 'Call configure() before using plugin methods'
},
[ErrorCode.INTERNAL_ERROR]: {
message: 'Internal error',
guidance: 'Check logs for details and report issue if persistent'
},
[ErrorCode.SYSTEM_ERROR]: {
message: 'System error',
guidance: 'Check system logs and platform-specific error details'
},
[ErrorCode.NOT_SUPPORTED]: {
message: 'Operation not supported',
guidance: 'This operation is not supported on this platform',
platformHints: {
web: 'Use native iOS or Android implementation for this feature'
}
},
};
/**
* Error response shape for cross-platform error handling
*

View File

@@ -23,6 +23,7 @@ import type {
History,
HistoryStats,
} from './definitions';
import { DailyNotificationError, ErrorCode } from './core/errors';
/**
* Web implementation of DailyNotificationPlugin
@@ -31,12 +32,15 @@ import type {
* are not supported on web platforms.
*/
export class DailyNotificationWeb implements DailyNotificationPlugin {
private static readonly WEB_NOT_SUPPORTED_ERROR =
'Daily notifications are not supported on web platforms. ' +
'Please use this plugin on iOS or Android.';
private throwNotSupported(): never {
throw new Error(DailyNotificationWeb.WEB_NOT_SUPPORTED_ERROR);
throw new DailyNotificationError(
ErrorCode.NOT_SUPPORTED,
'Daily notifications are not supported on web platforms. Please use this plugin on iOS or Android.',
{
guidance: 'Use native iOS or Android implementation for this feature',
platform: 'web'
}
);
}
async configure(): Promise<void> {
@@ -346,6 +350,32 @@ export class DailyNotificationWeb implements DailyNotificationPlugin {
this.throwNotSupported();
}
/**
* Get current plugin state (development only)
* @internal
*/
async getDebugState(): Promise<{
schedules: Schedule[];
configs: Config[];
callbacks: Callback[];
metrics: {
eventCount: number;
successRate: number;
avgFetchTime: number;
avgNotifyTime: number;
};
}> {
// Web implementation: debug methods not supported
throw new DailyNotificationError(
ErrorCode.NOT_SUPPORTED,
'Debug methods not available on web platform',
{
guidance: 'Use native iOS or Android implementation for debug features',
platform: 'web'
}
);
}
async enableSchedule(_id: string, _enabled: boolean): Promise<void> {
this.throwNotSupported();
}