mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 14:10:52 +01:00
Add TypeScript types for ExtensionError and improve error handling
- Add SerializedExtensionError TypeScript bindings from Rust - Add ExtensionErrorCode enum export with ts-rs - Create useExtensionError composable with type guards and error message extraction - Fix developer page toast messages to show proper error messages instead of [object Object] - Add getErrorMessage helper function for robust error handling across different error types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
6
src-tauri/bindings/ExtensionErrorCode.ts
Normal file
6
src-tauri/bindings/ExtensionErrorCode.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Error codes for frontend handling
|
||||
*/
|
||||
export type ExtensionErrorCode = "SecurityViolation" | "NotFound" | "PermissionDenied" | "MutexPoisoned" | "Database" | "Filesystem" | "FilesystemWithPath" | "Http" | "Shell" | "Manifest" | "Validation" | "InvalidPublicKey" | "InvalidSignature" | "InvalidActionString" | "SignatureVerificationFailed" | "CalculateHash" | "Installation";
|
||||
6
src-tauri/bindings/SerializedExtensionError.ts
Normal file
6
src-tauri/bindings/SerializedExtensionError.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Serialized representation of ExtensionError for TypeScript
|
||||
*/
|
||||
export type SerializedExtensionError = { code: number, type: string, message: string, extension_id: string | null, };
|
||||
@ -1,10 +1,12 @@
|
||||
// src-tauri/src/extension/error.rs
|
||||
use thiserror::Error;
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::database::error::DatabaseError;
|
||||
|
||||
/// Error codes for frontend handling
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, TS)]
|
||||
#[ts(export)]
|
||||
pub enum ExtensionErrorCode {
|
||||
SecurityViolation = 1000,
|
||||
NotFound = 1001,
|
||||
@ -25,6 +27,17 @@ pub enum ExtensionErrorCode {
|
||||
Installation = 5000,
|
||||
}
|
||||
|
||||
/// Serialized representation of ExtensionError for TypeScript
|
||||
#[derive(Debug, Clone, serde::Serialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct SerializedExtensionError {
|
||||
pub code: u16,
|
||||
#[serde(rename = "type")]
|
||||
pub error_type: String,
|
||||
pub message: String,
|
||||
pub extension_id: Option<String>,
|
||||
}
|
||||
|
||||
impl serde::Serialize for ExtensionErrorCode {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
||||
@ -163,8 +163,9 @@ const loadDevExtensionAsync = async () => {
|
||||
extensionPath.value = ''
|
||||
} catch (error) {
|
||||
console.error('Failed to load dev extension:', error)
|
||||
const { getErrorMessage } = useExtensionError()
|
||||
add({
|
||||
description: t('add.errors.loadFailed') + error,
|
||||
description: `${t('add.errors.loadFailed')}: ${getErrorMessage(error)}`,
|
||||
color: 'error',
|
||||
})
|
||||
} finally {
|
||||
@ -196,8 +197,9 @@ const reloadDevExtensionAsync = async (extension: ExtensionInfoResponse) => {
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to reload dev extension:', error)
|
||||
const { getErrorMessage } = useExtensionError()
|
||||
add({
|
||||
description: t('list.errors.reloadFailed') + error,
|
||||
description: `${t('list.errors.reloadFailed')}: ${getErrorMessage(error)}`,
|
||||
color: 'error',
|
||||
})
|
||||
}
|
||||
@ -223,8 +225,9 @@ const removeDevExtensionAsync = async (extension: ExtensionInfoResponse) => {
|
||||
await loadExtensionsAsync()
|
||||
} catch (error) {
|
||||
console.error('Failed to remove dev extension:', error)
|
||||
const { getErrorMessage } = useExtensionError()
|
||||
add({
|
||||
description: t('list.errors.removeFailed') + error,
|
||||
description: `${t('list.errors.removeFailed')}: ${getErrorMessage(error)}`,
|
||||
color: 'error',
|
||||
})
|
||||
}
|
||||
|
||||
43
src/composables/useExtensionError.ts
Normal file
43
src/composables/useExtensionError.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import type { SerializedExtensionError } from '~~/src-tauri/bindings/SerializedExtensionError'
|
||||
|
||||
/**
|
||||
* Type guard to check if error is a SerializedExtensionError
|
||||
*/
|
||||
export function isSerializedExtensionError(error: unknown): error is SerializedExtensionError {
|
||||
return (
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'code' in error &&
|
||||
'message' in error &&
|
||||
'type' in error
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract error message from unknown error type
|
||||
*/
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (isSerializedExtensionError(error)) {
|
||||
return error.message
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
return error.message
|
||||
}
|
||||
|
||||
if (typeof error === 'string') {
|
||||
return error
|
||||
}
|
||||
|
||||
return String(error)
|
||||
}
|
||||
|
||||
/**
|
||||
* Composable for handling extension errors
|
||||
*/
|
||||
export function useExtensionError() {
|
||||
return {
|
||||
isSerializedExtensionError,
|
||||
getErrorMessage,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user