From 6b424018eb1b414a0824e70f241c1bc47aa04017 Mon Sep 17 00:00:00 2001 From: dollaransh17 Date: Sat, 4 Oct 2025 01:12:01 +0530 Subject: [PATCH] improve(core): enhance code quality with better error handling and documentation - Add comprehensive JSDoc documentation for helper functions in application/helpers-common.ts - Improve error handling in Android native app initialization with try-catch block - Resolve TODO comment about custom application type handling - Enhance timeConverter function with input validation and better error messages - Improve cubic-bezier animation error message with detailed format expectations - Add proper return type annotations for background state functions - Better developer warnings when reflection fails during app initialization These improvements enhance code maintainability, provide better developer experience, and make error messages more actionable for debugging. --- packages/core/application/helpers-common.ts | 46 +++++++++++++++++---- packages/core/ui/styling/converters.ts | 21 +++++++++- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/packages/core/application/helpers-common.ts b/packages/core/application/helpers-common.ts index eb6209e1bd..567ffa0d37 100644 --- a/packages/core/application/helpers-common.ts +++ b/packages/core/application/helpers-common.ts @@ -56,12 +56,22 @@ export function getNativeApp(): T { // the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type if (!nativeApp) { - // TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module? - const clazz = java.lang.Class.forName('android.app.ActivityThread'); - if (clazz) { - const method = clazz.getMethod('currentApplication', null); - if (method) { - nativeApp = method.invoke(null, null); + // Handle custom application type by getting current application through reflection + // This is a fallback for cases where a custom application type is provided + // and the user has not explicitly initialized the application module + try { + const clazz = java.lang.Class.forName('android.app.ActivityThread'); + if (clazz) { + const method = clazz.getMethod('currentApplication', null); + if (method) { + nativeApp = method.invoke(null, null); + } + } + } catch (error) { + // Reflection failed, this is expected in some edge cases + // The app should still function, but without native app reference + if (__DEV__) { + console.warn('Failed to retrieve native application instance via reflection:', error); } } } @@ -83,19 +93,39 @@ export function setNativeApp(app: NativeApp) { let rootView: any; +/** + * Get the current root view of the application. + * @returns The current root view instance or undefined if not set. + */ export function getRootView() { return rootView; } +/** + * Set the root view of the application. + * This is typically called internally during application initialization. + * @param view The root view instance to set. + */ export function setRootView(view: any) { rootView = view; } let _appInBackground: boolean = false; -export function isAppInBackground() { + +/** + * Check if the application is currently in the background. + * @returns true if the app is in background, false if in foreground. + */ +export function isAppInBackground(): boolean { return _appInBackground; } -export function setAppInBackground(value: boolean) { + +/** + * Set the application background state. + * This is typically called internally when the app enters/exits background. + * @param value true if app is entering background, false if entering foreground. + */ +export function setAppInBackground(value: boolean): void { _appInBackground = value; } diff --git a/packages/core/ui/styling/converters.ts b/packages/core/ui/styling/converters.ts index 1af4b10c57..d4b92f765a 100644 --- a/packages/core/ui/styling/converters.ts +++ b/packages/core/ui/styling/converters.ts @@ -9,8 +9,25 @@ const STYLE_CURVE_MAP = Object.freeze({ spring: CoreTypes.AnimationCurve.spring, }); +/** + * Converts a time value string to milliseconds. + * Supports both 's' (seconds) and 'ms' (milliseconds) units. + * @param value The time value as a string (e.g., '1s', '500ms', '2.5') + * @returns Time in milliseconds, always >= 0 + * @throws Error if the input is not a valid time value + */ export function timeConverter(value: string): number { - let result = parseFloat(value); + if (!value || typeof value !== 'string') { + throw new Error(`Invalid time value: '${value}'. Expected a string with time value.`); + } + + const numericValue = parseFloat(value); + if (isNaN(numericValue)) { + throw new Error(`Invalid time value: '${value}'. Expected a numeric value with optional 's' or 'ms' unit.`); + } + + let result = numericValue; + // Convert seconds to milliseconds if 'ms' is not specified if (value.indexOf('ms') === -1) { result = result * 1000; } @@ -31,7 +48,7 @@ function parseCubicBezierCurve(value: string) { return CoreTypes.AnimationCurve.cubicBezier(x1, x2, y1, y2); } else { - throw new Error(`Invalid value for animation: ${value}`); + throw new Error(`Invalid cubic-bezier animation timing function: '${value}'. Expected format: cubic-bezier(x1, y1, x2, y2) where coordinates are between 0 and 1.`); } }