-
Notifications
You must be signed in to change notification settings - Fork 9
Claude's suggestion for code improvements #1204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Ambiguous Types and Inappropriate 'any' Usage Report | ||
|
|
||
| Based on the search through the TypeScript files in the packages/ directory, I've found several patterns of inappropriate type usage according to AGENTS.md guidelines: | ||
|
|
||
| ## 1. Direct Usage of 'any' Type | ||
|
|
||
| ### packages/runner/src/utils.ts | ||
| - **Line 31**: `extractDefaultValues(schema: any): any` - Function accepts and returns 'any' without proper type validation | ||
| - **Line 35**: `const obj: any = {}` - Local variable using 'any' | ||
| - **Line 58**: `mergeObjects(...objects: any[]): any` - Function accepts array of 'any' and returns 'any' | ||
| - **Line 64**: `const result: any = {}` - Local variable using 'any' | ||
| - **Line 107-110**: `sendValueToBinding(doc: DocImpl<any>, binding: any, value: any, log?: ReactivityLog)` - Multiple 'any' parameters | ||
| - **Line 137-139**: `setNestedValue(doc: DocImpl<any>, path: PropertyKey[], value: any, log?: ReactivityLog)` - 'any' in generic and parameter | ||
| - **Line 167-169**: Multiple functions in traverse.ts using 'any' parameters (lines ~221-224) | ||
| - **Line 256**: `unsafe_noteParentOnRecipes(recipe: Recipe, binding: any)` - Accepts 'any' parameter | ||
| - **Line 283**: `findAllAliasedCells(binding: any, doc: DocImpl<any>)` - Multiple 'any' usage | ||
| - **Line 540-546**: `maybeGetCellLink(value: any, parent?: DocImpl<any>)` - 'any' parameters | ||
| - **Line 555**: `followAliases(alias: any, doc: DocImpl<any>, log?: ReactivityLog)` - 'any' parameter | ||
| - **Line 583**: `diffAndUpdate(current: CellLink, newValue: any, log?: ReactivityLog, context?: any)` - Multiple 'any' | ||
| - **Line 616-620**: `normalizeAndDiff(current: CellLink, newValue: any, log?: ReactivityLog, context?: any)` - Multiple 'any' | ||
| - **Line 896**: `addCommonIDfromObjectID(obj: any, fieldName: string = "id")` - 'any' parameter | ||
| - **Line 915**: `maybeUnwrapProxy(value: any): any` - Accepts and returns 'any' | ||
| - **Line 932**: `containsOpaqueRef(value: any): boolean` - 'any' parameter | ||
| - **Line 941**: `deepCopy(value: any): any` - Accepts and returns 'any' | ||
|
|
||
| ### packages/js-runtime/interface.ts | ||
| - **Line 12**: `invoke(...args: any[]): JsValue` - Array of 'any' as parameters | ||
| - **Line 13**: `inner(): any` - Returns 'any' | ||
|
|
||
| ### packages/builder/src/built-in.ts | ||
| - **Line 24**: `error: any` - Property typed as 'any' | ||
| - **Line 44**: `error: any` - Property typed as 'any' | ||
| - **Line 55**: `error: any` - Property typed as 'any' | ||
| - **Line 57**: `ifElse<T = any, U = any, V = any>` - Generic parameters defaulting to 'any' | ||
| - **Line 69**: `let ifElseFactory: NodeFactory<[any, any, any], any> | undefined` - Multiple 'any' in generic | ||
| - **Line 74**: `(cell: OpaqueRef<any>) => OpaqueRef<string>` - 'any' in generic | ||
| - **Line 82**: `...values: any[]` - Array of 'any' | ||
| - **Line 89**: `values: any[]` - Array of 'any' | ||
|
|
||
| ### packages/memory/traverse.ts | ||
| - **Line 167-169**: `[k, this.traverseDAG(doc, docRoot, v, tracker)]),` - Using 'any' in type assertion | ||
| - **Line 355**: `isPointer(value: any): boolean` - 'any' parameter | ||
| - **Line 365**: `isJSONCellLink(value: any): value is JSONCellLink` - 'any' parameter | ||
| - **Line 371-379**: Multiple functions accepting 'any' parameters | ||
|
|
||
| ### packages/html/src/render.ts | ||
| - **Line 60-70**: Comments indicate potential issues with type handling but implementation uses proper types | ||
|
|
||
| ## 2. Type Assertions Using 'as any' | ||
|
|
||
| ### packages/runner/src/runner.ts | ||
| - **Line ~224**: Type assertion `as any` in runtime context | ||
|
|
||
| ### packages/runner/src/cell.ts | ||
| - **Line ~118**: `(self.key as any)(key).set(value)` - Type assertion to bypass type checking | ||
|
|
||
| ### packages/runner/src/query-result-proxy.ts | ||
| - **Line ~42**: `const target = valueCell.getAtPath(valuePath) as any` - Type assertion | ||
| - **Line ~120**: `undefined as unknown as any[]` - Multiple type assertions | ||
|
|
||
| ### packages/builder/src/spell.ts | ||
| - **Line ~25**: `if (typeof prop === "symbol") return (target as any)[prop]` - Type assertion | ||
| - **Line ~48**: `[key, (self as any)[key]]` - Type assertion in mapping | ||
|
|
||
| ### packages/builder/src/utils.ts | ||
| - **Line ~117**: `for (const key in value as any)` - Type assertion in loop | ||
|
|
||
| ### packages/builder/src/recipe.ts | ||
| - **Lines ~182-186**: Multiple `as any` assertions when deleting properties | ||
|
|
||
| ### packages/memory/traverse.ts | ||
| - **Line ~169**: Type assertion in mapping function | ||
|
|
||
| ## 3. Overly Broad Union Types | ||
|
|
||
| While I didn't find the specific pattern `string | number | object | null`, there are several places with overly permissive types: | ||
|
|
||
| ### packages/builder/src/types.ts | ||
| - **Line ~244**: `cell?: any` in Alias type - Should be more specific | ||
| - **Line ~263**: `implementation?: ((...args: any[]) => any) | Recipe | string` - Function signature with 'any' | ||
|
|
||
| ## 4. Functions Accepting Overly Broad Types Without Validation | ||
|
|
||
| ### packages/runner/src/utils.ts | ||
| - `extractDefaultValues`, `mergeObjects`, `sendValueToBinding`, `setNestedValue` - All accept 'any' without proper type guards or validation | ||
| - These functions perform operations on the values but don't validate the types first | ||
|
|
||
| ### packages/memory/traverse.ts | ||
| - Multiple traversal functions accept 'any' or 'unknown' without proper validation | ||
|
|
||
| ## 5. Unknown Types That Should Be More Specific | ||
|
|
||
| ### packages/js-runtime/interface.ts | ||
| - **Lines 70-79**: `isJsModule` function uses 'unknown' but could use a more specific base type | ||
| - **Lines 97-104**: `isSourceMap` function uses 'unknown' but could use a more specific base type | ||
|
|
||
| ### packages/memory/traverse.ts | ||
| - **Lines 371-389**: Multiple functions use 'unknown' parameters that could be more specific | ||
|
||
|
|
||
| ## Recommendations | ||
|
|
||
| 1. **Replace 'any' with specific types or generics** where possible | ||
| 2. **Add proper type guards** for functions that need to accept broad types | ||
| 3. **Use discriminated unions** instead of 'any' for values that can be multiple types | ||
| 4. **Avoid type assertions** (`as any`) - instead, use type guards or proper typing | ||
| 5. **Document why 'any' is necessary** in the few cases where it truly is needed | ||
| 6. **Consider using 'unknown'** instead of 'any' and add type guards for safety | ||
|
|
||
| ## Priority Files to Fix | ||
|
|
||
| 1. **packages/runner/src/utils.ts** - Has the most 'any' usage | ||
| 2. **packages/builder/src/built-in.ts** - Core functionality with multiple 'any' | ||
| 3. **packages/memory/traverse.ts** - Complex traversal logic with 'any' | ||
| 4. **packages/builder/src/types.ts** - Type definitions themselves use 'any' | ||
| 5. **packages/js-runtime/interface.ts** - Interface definitions with 'any' | ||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,282 @@ | ||
| # Inappropriate Error Handling Report | ||
|
||
|
|
||
| Based on the analysis of the codebase against AGENTS.md guidelines, the | ||
| following inappropriate error handling patterns were found: | ||
|
|
||
| ## 1. Try/catch Blocks That Silently Swallow Errors | ||
|
|
||
| ### `packages/jumble/src/components/NetworkInspector.tsx` | ||
|
|
||
| **Lines**: 236-238 | ||
|
|
||
| ```typescript | ||
| } catch (e) { | ||
| return null; | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Silently catches errors and returns null without any logging or | ||
| re-throwing. This makes debugging impossible and hides potential issues. | ||
|
|
||
| ### `packages/toolshed/lib/otel.ts` | ||
|
|
||
| **Lines**: 60-62 | ||
|
|
||
| ```typescript | ||
| } catch (_) { | ||
| // ignored – not running on Deno with telemetry support | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Empty catch block that completely swallows errors. Even if the error | ||
| is expected, it should at least be logged for debugging purposes. | ||
|
|
||
| ## 2. Different Error Handling Approaches in the Same Code Path | ||
|
|
||
| ### `packages/runner/src/runner.ts` | ||
|
|
||
| **Lines**: 358-363 | ||
|
|
||
| ```typescript | ||
| try { | ||
| cancel(); | ||
| } catch (error) { | ||
| console.warn("Error canceling operation:", error); | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Uses `console.warn` for errors in a method that should likely | ||
| propagate errors up to the caller for proper handling. | ||
|
|
||
| ### `packages/js-runtime/typescript/compiler.ts` | ||
|
|
||
| **Lines**: 111-114 | ||
|
|
||
| ```typescript | ||
| } catch (e) { | ||
| console.warn(`There was an error parsing "${key}" source map: ${e}`); | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Uses `console.warn` instead of throwing or properly handling the | ||
| parsing error. Source map parsing errors could indicate serious issues. | ||
|
|
||
| ### `packages/llm/src/client.ts` | ||
|
|
||
| **Lines**: 101-103, 115-117 | ||
|
|
||
| ```typescript | ||
| } catch (error) { | ||
| console.error("Failed to parse JSON line:", line, error); | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Logs errors to console instead of propagating them, while other parts | ||
| of the same method throw errors. This creates inconsistent error handling. | ||
|
|
||
| ## 3. Functions Returning undefined/null on Error Instead of Throwing | ||
|
|
||
| ### `packages/jumble/src/components/NetworkInspector.tsx` | ||
|
|
||
| **Lines**: 213-239 | ||
|
|
||
| ```typescript | ||
| const extractTransactionDetails = (value: any): any => { | ||
| try { | ||
| // ... processing logic ... | ||
| } catch (e) { | ||
| return null; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| **Issue**: Returns null on any error instead of throwing or properly handling | ||
| specific error cases. Callers can't distinguish between "no data" and "error | ||
| occurred". | ||
|
|
||
| ### `packages/ui/src/components/common-form.ts` | ||
|
||
|
|
||
| **Lines**: 64-66 | ||
|
|
||
| ```typescript | ||
| } catch { | ||
| return "Invalid reference format"; | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Returns an error string instead of throwing, inconsistent with other | ||
| validation patterns that throw errors. | ||
|
|
||
| ### `packages/charm/src/spellbook.ts` | ||
|
|
||
| ```typescript | ||
| } catch (error) { | ||
| console.error("Failed to save spell:", error); | ||
| return false; | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Returns false on error instead of throwing, preventing callers from | ||
| understanding why the operation failed. | ||
|
|
||
| ## 4. Overly Broad try/catch Blocks | ||
|
|
||
| ### `packages/charm/src/manager.ts` | ||
|
|
||
| **Lines**: 500-700+ | ||
|
|
||
| ```typescript | ||
| try { | ||
| // Hundreds of lines of code including: | ||
| // - Multiple async operations | ||
| // - Complex data transformations | ||
| // - Nested function calls | ||
| } catch (error) { | ||
| console.debug("Error in findReferencedCharms:", error); | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Try block covers too much code, making it difficult to understand | ||
| which operation actually failed. Errors from very different operations are | ||
| handled identically. | ||
|
|
||
| ## 5. Low-level try/catch Where Errors Should Propagate | ||
|
|
||
| ### `packages/charm/src/workflow.ts` | ||
|
|
||
| Multiple instances of: | ||
|
|
||
| ```typescript | ||
| try { | ||
| // Some operation | ||
| } catch (error) { | ||
| console.warn("Operation failed:", error); | ||
| // Continues execution | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Error handling at the workflow processing level prevents higher-level | ||
| error handlers from taking appropriate action (retry, fallback, user | ||
| notification). | ||
|
|
||
| ### `packages/background-charm-service/src/worker.ts` | ||
|
|
||
| **Lines**: 186-188 | ||
|
|
||
| ```typescript | ||
| } catch (error) { | ||
| const errorMessage = String(error); | ||
| // Loses stack trace and error type information | ||
| } | ||
| ``` | ||
|
|
||
| **Issue**: Converts errors to strings, losing valuable debugging information | ||
| like stack traces and error types. | ||
|
|
||
| ## 6. Missing Error Context or Unhelpful Error Messages | ||
|
|
||
| ### `packages/toolshed/routes/integrations/google-oauth/google-oauth.utils.ts` | ||
|
|
||
| **Lines**: 162, 195 | ||
|
|
||
| ```typescript | ||
| throw new Error(`Failed to get auth cell: ${error}`); | ||
| throw new Error(`Error persisting tokens: ${error}`); | ||
| ``` | ||
|
|
||
| **Issue**: Simply wraps errors without adding meaningful context about what was | ||
| being attempted, what the inputs were, or suggestions for resolution. | ||
|
|
||
| ## 7. Console Logging in Production Code | ||
|
|
||
| Multiple files use console methods for error handling instead of proper error | ||
| propagation: | ||
|
|
||
| - `packages/charm/src/format.ts` - Uses `console.error` | ||
| - `packages/charm/src/search.ts` - Uses `console.warn` | ||
| - `packages/charm/src/workflow.ts` - Mixed `console.warn` and `console.error` | ||
| - `packages/charm/src/iframe/recipe.ts` - Uses `console.log` for errors | ||
|
|
||
| **Issue**: Console logging is not appropriate for production error handling. | ||
| Errors should be propagated or logged through proper logging mechanisms. | ||
|
|
||
| ## Recommendations Based on AGENTS.md | ||
|
|
||
| ### 1. Let Errors Propagate | ||
|
|
||
| ```typescript | ||
| // Good - let caller handle the error | ||
| async function getData(): Promise<string> { | ||
| const res = await fetch(URL); | ||
| if (res.ok) { | ||
| return res.text(); | ||
| } | ||
| throw new Error("Unsuccessful HTTP response"); | ||
| } | ||
|
|
||
| // Bad - swallowing errors | ||
| async function getData(): Promise<string | undefined> { | ||
| try { | ||
| const res = await fetch(URL); | ||
| if (res.ok) { | ||
| return res.text(); | ||
| } | ||
| } catch (e) { | ||
| console.error(e); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 2. Only Catch When You Can Handle | ||
|
|
||
| ```typescript | ||
| // Good - specific error handling with retry | ||
| async function fetchWithRetry(url: string, retries = 3): Promise<Response> { | ||
| for (let i = 0; i < retries; i++) { | ||
| try { | ||
| return await fetch(url); | ||
| } catch (error) { | ||
| if (i === retries - 1) throw error; | ||
| await delay(1000 * Math.pow(2, i)); // exponential backoff | ||
| } | ||
| } | ||
| throw new Error("Should not reach here"); | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. Add Meaningful Context | ||
|
|
||
| ```typescript | ||
| // Good - adds context to errors | ||
| try { | ||
| await saveUserData(userId, data); | ||
| } catch (error) { | ||
| throw new Error( | ||
| `Failed to save data for user ${userId}: ${error.message}`, | ||
| { cause: error }, | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| ### 4. Use Type Guards for Expected Errors | ||
|
|
||
| ```typescript | ||
| // Good - handle specific, expected scenarios | ||
| function isFeatureSupported(): boolean { | ||
| try { | ||
| // Try to use feature | ||
| crypto.subtle.importKey(...); | ||
| return true; | ||
| } catch { | ||
| // Expected error - feature not supported | ||
| return false; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Priority Areas to Fix | ||
|
|
||
| 1. **High Priority**: Error swallowing in core libraries (`runner`, `builder`, | ||
| `charm`) | ||
| 2. **Medium Priority**: Console logging instead of proper error handling | ||
| 3. **Low Priority**: Missing error context in utility functions | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document hard-codes exact source line numbers (e.g. Line 31) which will quickly become stale as code evolves, making the report misleading and harder to maintain.