Skip to content

bug(extension): unhandled exception on invalid install source #312

@margaretjgu

Description

@margaretjgu

Summary

elastic extension install <bad-source> dumps a raw Node.js stack trace to the terminal instead of a clean user-facing error message.

Steps to reproduce

elastic extension install bad-source

Actual behaviour

file:///dist/extension/installer.js:69
        throw new Error(`Invalid GitHub source "bad-source". Use github:owner/repo or owner/repo.`);
              ^

Error: Invalid GitHub source "bad-source". ...
    at parseSource (installer.js:69)
    at installExtension (installer.js:190)
    at handleInstall (register.js:41)
    ...
Node.js v24.9.0

Expected behaviour

Error: Invalid GitHub source "bad-source". Use github:owner/repo or owner/repo.

Root cause

handleInstall (and handleUpgrade, handleRemove) in src/extension/register.ts do not wrap calls to installExtension / upgradeExtension / uninstallExtension in a try-catch. The factory only converts { error: { code } } return values to clean errors; thrown exceptions propagate uncaught to Node.js.

Fix

Wrap installer calls in register.ts to return structured error objects instead of throwing:

async function handleInstall(parsed: { arg?: string }): Promise<JsonValue> {
  const source = parsed.arg?.trim()
  if (!source) return { error: { code: 'missing_source', message: '...' } }
  try {
    const entry = await installExtension(source)
    return { installed: true, ...entry } as unknown as JsonValue
  } catch (err: unknown) {
    return {
      error: {
        code: 'install_failed',
        message: err instanceof Error ? err.message : String(err),
      },
    } as unknown as JsonValue
  }
}

Same pattern needed for handleUpgrade and handleRemove.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions