Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问clear审计通过

elixir-antipatternsElixir antipatterns 搜索

Agent Skill

elixir-antipatterns 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,734

周安装

73

GitHub Stars

488

下载量

607
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:elixir-antipatterns(Elixir antipatterns 搜索)
来源仓库:https://github.com/gentleman-programming/gentleman-skills
仓库路径:skills/elixir-antipatterns
安装命令:
npx skills add https://github.com/gentleman-programming/gentleman-skills --skill elixir-antipatterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/gentleman-programming/gentleman-skills --skill elixir-antipatterns

简介

elixir-antipatterns 提供关键反模式清单,涵盖错误处理、架构、性能和测试等方面。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中审查 Ecto 查询、GenServer 实现或 Phoenix 控制器。
  • 可作为补充参考,配合 mix format 和 Credo 进行风格与质量管控。
  • 安装前请确认是否需要深度示例,必要时查阅 EXTENDED.md 获取更多模式细节。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Elixir Anti-Patterns

Critical anti-patterns that compromise robustness and maintainability in Elixir/Phoenix applications.

Complement with: mix format and Credo for style enforcement Extended reference: See EXTENDED.md for 40+ patterns and deep-dive examples

When to Use

Topics: Error handling (3 patterns) • Architecture (2 patterns) • Performance (2 patterns) • Testing (1 pattern)

Load this skill when:

  • Writing Elixir modules and functions
  • Working with Phoenix Framework (Controllers, LiveView)
  • Building Ecto schemas and database queries
  • Implementing BEAM concurrency (Task, GenServer)
  • Handling errors with tagged tuples
  • Writing tests with ExUnit

Critical Patterns

Quick reference to the 8 core patterns this skill enforces:

  1. Tagged Tuples: Return {:ok, value} | {:error, reason} instead of nil or exceptions
  2. Explicit @spec: Document error cases in function signatures
  3. Context Separation: Business logic in contexts, not LiveView
  4. Preload Associations: Use Repo.preload/2 to avoid N+1 queries
  5. with Arrow Binding: Use <- for all failable operations in with
  6. Database Indexes: Index frequently queried columns
  7. Test Assertions: Every test must assert expected behavior
  8. Cohesive Functions: Group with chains >4 steps into functions
See ## Anti-Patterns section below for detailed ❌ BAD / ✅ CORRECT code examples.

Code Examples

Example 1: Error Handling with Tagged Tuples

# ✅ CORRECT - Errors as values, explicit in @spec
defmodule UserService do
  @spec fetch_user(String.t()) :: {:ok, User.t()} | {:error, :not_found}
  def fetch_user(id) do
    case Repo.get(User, id) do
      nil -> {:error, :not_found}
      user -> {:ok, user}
    end
  end
end

# ❌ BAD - Exceptions for business errors
def fetch_user(id) do
  Repo.get(User, id) || raise "User not found"
end

Example 2: Phoenix LiveView with Context Separation

Architecture Layers:
  User Request → LiveView (UI only) → Context (business logic) → Schema/Repo (data)
               ↓                    ↓                           ↓
           handle_event()     Accounts.create_user()      Repo.insert()
# ✅ CORRECT - Thin LiveView, logic in context
defmodule MyAppWeb.UserLive.Index do
  use MyAppWeb, :live_view

  def handle_event("create", params, socket) do
    case Accounts.create_user(params) do
      {:ok, user} -> {:noreply, redirect(socket, to: ~p"/users/#{user}")}
      {:error, changeset} -> {:noreply, assign(socket, changeset: changeset)}
    end
  end
end

# ❌ BAD - Business logic in LiveView
def handle_event("create", %{"user" => params}, socket) do
  if String.length(params["name"]) < 3 do
    {:noreply, put_flash(socket, :error, "Too short")}
  else
    case Repo.insert(User.changeset(%User{}, params)) do
      {:ok, user} -> send_email(user); redirect(socket)
    end
  end
end

Example 3: Ecto N+1 Query Optimization

# ✅ CORRECT - Preload associations (2 queries total)
users = User |> Repo.all() |> Repo.preload(:posts)
Enum.map(users, fn user -> process(user, user.posts) end)

# Note: For complex filtering (e.g., WHERE posts.status = 'published'),
# use join + preload in the query itself. See EXTENDED.md for advanced patterns.

# ❌ BAD - Query in loop (101 queries for 100 users)
users = Repo.all(User)
Enum.map(users, fn user ->
  posts = Repo.all(from p in Post, where: p.user_id == ^user.id)
  {user, posts}
end)

Anti-Patterns

Error Management

Don't: Use raise for Business Errors

# ❌ BAD
def fetch_user(id) do
  Repo.get(User, id) || raise "User not found"
end

# ✅ CORRECT
@spec fetch_user(String.t()) :: {:ok, User.t()} | {:error, :not_found}
def fetch_user(id) do
  case Repo.get(User, id) do
    nil -> {:error, :not_found}
    user -> {:ok, user}
  end
end

Why: @spec documents errors, pattern matching forces explicit handling.


Don't: Return nil for Errors

# ❌ BAD - No context on failure
def find_user(email), do: Repo.get_by(User, email: email)

# ✅ CORRECT - Explicit error reason
@spec find_user(String.t()) :: {:ok, User.t()} | {:error, :not_found}
def find_user(email) do
  case Repo.get_by(User, email: email) do
    nil -> {:error, :not_found}
    user -> {:ok, user}
  end
end

Don't: Use = Inside with for Failable Operations

# ❌ BAD - Validate errors silenced
with {:ok, user} <- fetch_user(id),
     validated = validate(user),  # ← Doesn't check for {:error, _}
     {:ok, saved} <- save(validated) do
  {:ok, saved}
end

# ✅ CORRECT - All operations use <-
with {:ok, user} <- fetch_user(id),
     {:ok, validated} <- validate(user),
     {:ok, saved} <- save(validated) do
  {:ok, saved}
end

Architecture & Boundaries

Don't: Put Business Logic in LiveView

# ❌ BAD - Validation in view
def handle_event("create", %{"user" => params}, socket) do
  if String.length(params["name"]) < 3 do
    {:noreply, put_flash(socket, :error, "Too short")}
  else
    case Repo.insert(User.changeset(%User{}, params)) do
      {:ok, user} -> redirect(socket)
    end
  end
end

# ✅ CORRECT - Delegate to context
def handle_event("create", params, socket) do
  case Accounts.create_user(params) do
    {:ok, user} -> {:noreply, redirect(socket, to: ~p"/users/#{user}")}
    {:error, changeset} -> {:noreply, assign(socket, changeset: changeset)}
  end
end

Why: Contexts testable without Phoenix, logic reusable.


Don't: Chain More Than 4 Steps in with

# ❌ BAD - Too many responsibilities
with {:ok, a} <- step1(),
     {:ok, b} <- step2(a),
     {:ok, c} <- step3(b),
     {:ok, d} <- step4(c),
     {:ok, e} <- step5(d) do
  {:ok, e}
end

# ✅ CORRECT - Group into cohesive functions
with {:ok, validated} <- validate_and_fetch(id),
     {:ok, processed} <- process_business_rules(validated),
     {:ok, result} <- persist_and_notify(processed) do
  {:ok, result}
end

Data & Performance

Don't: Query Inside Loops (N+1)

# ❌ BAD - 101 queries for 100 users
users = Repo.all(User)
Enum.map(users, fn user ->
  posts = Repo.all(from p in Post, where: p.user_id == ^user.id)
end)

# ✅ CORRECT - 2 queries total
User |> Repo.all() |> Repo.preload(:posts)

Impact: 100 users with N+1 = 10 seconds vs 5ms with preload.


Don't: Query Without Indexes

# ❌ BAD - No index on frequently queried column
# Migration:
create table(:users) do
  add :email, :string
end

# ✅ CORRECT - Add index
create table(:users) do
  add :email, :string
end
create unique_index(:users, [:email])

Why: Full table scan on 1M+ rows vs instant index lookup.


Testing

Don't: Write Tests Without Assertions

# ❌ BAD - What's being tested?
test "creates user" do
  UserService.create_user(%{name: "Juan"})
end

# ✅ CORRECT - Assert expected behavior
test "creates user successfully" do
  assert {:ok, user} = UserService.create_user(%{name: "Juan"})
  assert user.name == "Juan"
end

Quick Reference

SituationAnti-PatternCorrect Pattern
Error handlingraise "Not found"{:error,:not_found}
Missing dataReturn nil{:error,:not_found}
Business logicIn LiveViewIn context modules
AssociationsEnum.map + Repo.getRepo.preload
with chainsvalidated = fn(){:ok, validated} <- fn()
Frequent queriesNo indexcreate index(:table, [:column])
TestingNo assertionsassert expected behavior
Complex logic6+ step withGroup into 3 functions

Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

30.12%
按下载量换算183

Antigravity

25.37%
按下载量换算154

OpenCode

18.84%
按下载量换算114

Codex

11.7%
按下载量换算71

Gemini CLI

8.39%
按下载量换算51

windsurf

3.69%
按下载量换算22

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills