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:
@@ -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';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
40
src/web.ts
40
src/web.ts
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user