Always use proper Error objects when throwing exceptions, maintain consistent error handling contracts, and ensure type safety in error scenarios. Avoid throwing primitive strings, mixing throw/return patterns, or unsafe type assertions on error objects.
Always use proper Error objects when throwing exceptions, maintain consistent error handling contracts, and ensure type safety in error scenarios. Avoid throwing primitive strings, mixing throw/return patterns, or unsafe type assertions on error objects.
Key principles:
throw new Error('message')
instead of throw 'message'
undefined
on failure, don’t throw insteaderror instanceof Error
) before accessing propertiesExample of problematic patterns:
// Bad: throwing string
throw `External error with reported id was not registered`
// Bad: inconsistent with function signature that returns undefined
lookupError(error: number): ErrorRecord | undefined {
if (!errorRecord) throw `External error with reported id was not registered`
return errorRecord
}
// Bad: unsafe destructuring from any
catch (e) {
const { message } = e // e is any, not type-safe
}
Example of improved patterns:
// Good: proper Error object
throw new Error('External error with reported id was not registered')
// Good: consistent with signature
lookupError(error: number): ErrorRecord | undefined {
const errorRecord = this.registeredErrors[error]
return errorRecord // returns undefined if not found
}
// Good: type-safe error handling
catch (error) {
if (error instanceof Error) {
return err(error.cause)
}
throw error
}
Enter the URL of a public GitHub repository