重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
rust-errors by epicenterhq/epicenter
npx skills add https://github.com/epicenterhq/epicenter --skill rust-errors在以下场景中使用此模式:
name 和 message 字段的一致性。当通过 Tauri 命令将错误从 Rust 传递到 TypeScript 时,使用内部标记枚举来创建 TypeScript 可以自然处理的可区分联合。
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Error, Debug, Serialize, Deserialize)]
#[serde(tag = "name")]
pub enum TranscriptionError {
#[error("Audio read error: {message}")]
AudioReadError { message: String },
#[error("GPU error: {message}")]
GpuError { message: String },
#[error("Model load error: {message}")]
ModelLoadError { message: String },
#[error("Transcription error: {message}")]
TranscriptionError { message: String },
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
#[serde(tag = "name")] 创建一个鉴别器字段message: String 这样的字段// 为保持一致性使用单变体枚举
#[derive(Error, Debug, Serialize, Deserialize)]
#[serde(tag = "name")]
enum ArchiveExtractionError {
#[error("Archive extraction failed: {message}")]
ArchiveExtractionError { message: String },
}
import { type } from 'arktype';
// 定义错误类型以匹配 Rust 序列化
const TranscriptionErrorType = type({
name: "'AudioReadError' | 'GpuError' | 'ModelLoadError' | 'TranscriptionError'",
message: 'string',
});
// 在错误处理中使用
const result = await tryAsync({
try: () => invoke('transcribe_audio_whisper', params),
catch: (unknownError) => {
const result = TranscriptionErrorType(unknownError);
if (result instanceof type.errors) {
// 处理意外的错误形状
return WhisperingErr({
title: 'Unexpected Error',
description: extractErrorMessage(unknownError),
action: { type: 'more-details', error: unknownError },
});
}
const error = result;
// 现在我们有了正确类型的可区分联合
switch (error.name) {
case 'ModelLoadError':
return WhisperingErr({
title: 'Model Loading Error',
description: error.message,
action: {
type: 'more-details',
error: new Error(error.message),
},
});
case 'GpuError':
return WhisperingErr({
title: 'GPU Error',
description: error.message,
action: {
type: 'link',
label: 'Configure settings',
href: '/settings/transcription',
},
});
// 处理其他情况...
}
},
});
Rust 枚举序列化为以下 TypeScript 友好的格式:
// AudioReadError 变体
{ "name": "AudioReadError", "message": "Failed to decode audio file" }
// GpuError 变体
{ "name": "GpuError", "message": "GPU acceleration failed" }
name 和 messagecontent 属性 : 避免 #[serde(tag = "name", content = "data")],因为它会创建嵌套结构// 不要:外部标记(默认行为)
#[derive(Serialize)]
pub enum BadError {
ModelLoadError { message: String }
}
// 产生:{ "ModelLoadError": { "message": "..." } }
// 不要:带有内容的相邻标记
#[derive(Serialize)]
#[serde(tag = "type", content = "data")]
pub enum BadError {
ModelLoadError { message: String }
}
// 产生:{ "type": "ModelLoadError", "data": { "message": "..." } }
// 不要:在 derive 可用时手动实现 Serialize
impl Serialize for MyError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> {
// 不必要的复杂性
}
}
此模式确保了在 Rust-TypeScript 边界上进行干净、类型安全的错误处理,同时具有最少的样板代码和最大的类型安全性。
每周安装次数
70
仓库
GitHub 星标数
4.3K
首次出现
2026年1月20日
安全审计
已安装于
opencode61
codex60
claude-code59
gemini-cli59
cursor56
github-copilot54
Use this pattern when you need to:
name and message fields.When passing errors from Rust to TypeScript through Tauri commands, use internally-tagged enums to create discriminated unions that TypeScript can handle naturally.
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Error, Debug, Serialize, Deserialize)]
#[serde(tag = "name")]
pub enum TranscriptionError {
#[error("Audio read error: {message}")]
AudioReadError { message: String },
#[error("GPU error: {message}")]
GpuError { message: String },
#[error("Model load error: {message}")]
ModelLoadError { message: String },
#[error("Transcription error: {message}")]
TranscriptionError { message: String },
}
#[serde(tag = "name")] creates a discriminator fieldmessage: String// Single-variant enum for consistency
#[derive(Error, Debug, Serialize, Deserialize)]
#[serde(tag = "name")]
enum ArchiveExtractionError {
#[error("Archive extraction failed: {message}")]
ArchiveExtractionError { message: String },
}
import { type } from 'arktype';
// Define the error type to match Rust serialization
const TranscriptionErrorType = type({
name: "'AudioReadError' | 'GpuError' | 'ModelLoadError' | 'TranscriptionError'",
message: 'string',
});
// Use in error handling
const result = await tryAsync({
try: () => invoke('transcribe_audio_whisper', params),
catch: (unknownError) => {
const result = TranscriptionErrorType(unknownError);
if (result instanceof type.errors) {
// Handle unexpected error shape
return WhisperingErr({
title: 'Unexpected Error',
description: extractErrorMessage(unknownError),
action: { type: 'more-details', error: unknownError },
});
}
const error = result;
// Now we have properly typed discriminated union
switch (error.name) {
case 'ModelLoadError':
return WhisperingErr({
title: 'Model Loading Error',
description: error.message,
action: {
type: 'more-details',
error: new Error(error.message),
},
});
case 'GpuError':
return WhisperingErr({
title: 'GPU Error',
description: error.message,
action: {
type: 'link',
label: 'Configure settings',
href: '/settings/transcription',
},
});
// Handle other cases...
}
},
});
The Rust enum serializes to this TypeScript-friendly format:
// AudioReadError variant
{ "name": "AudioReadError", "message": "Failed to decode audio file" }
// GpuError variant
{ "name": "GpuError", "message": "GPU acceleration failed" }
name and messagecontent attribute: Avoid #[serde(tag = "name", content = "data")] as it creates nested structures// DON'T: External tagging (default behavior)
#[derive(Serialize)]
pub enum BadError {
ModelLoadError { message: String }
}
// Produces: { "ModelLoadError": { "message": "..." } }
// DON'T: Adjacent tagging with content
#[derive(Serialize)]
#[serde(tag = "type", content = "data")]
pub enum BadError {
ModelLoadError { message: String }
}
// Produces: { "type": "ModelLoadError", "data": { "message": "..." } }
// DON'T: Manual Serialize implementation when derive works
impl Serialize for MyError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> {
// Unnecessary complexity
}
}
This pattern ensures clean, type-safe error handling across the Rust-TypeScript boundary with minimal boilerplate and maximum type safety.
Weekly Installs
70
Repository
GitHub Stars
4.3K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode61
codex60
claude-code59
gemini-cli59
cursor56
github-copilot54
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
122,000 周安装
创始人销售指南:16位专家见解,助你建立可复制的早期销售流程 | Founder-Sales
1,000 周安装
多智能体编排指南:CrewAI、AutoGen、LangGraph框架实战,构建协同AI系统
1,000 周安装
大语言模型微调专家指南:LoRA/PEFT方法、数据集准备与生产部署优化
1,100 周安装
遗留系统现代化改造工具:安全迁移、绞杀者模式、特性测试指南
1,000 周安装
GraphQL架构师指南:Apollo联邦、模式设计与性能优化最佳实践
1,000 周安装
Feature Forge:AI驱动的功能规格定义工具,结构化需求工作坊
1,100 周安装