using-result-and-error-codes
Skill1 starsChanged 3 months agoMITView on GitHub
Use when handling domain errors, adding exception classes, or working with the LEX_ERR_* error code system in Lexigram
In this repository17 other files it gives its agents.
- ai-subsystem-quickstartSkill
- auth-and-securitySkill
- caching-patternsSkill
- cli-code-generationSkill
- cli-config-and-inspectSkill
- cli-database-operationsSkill
- cli-project-scaffoldingSkill
- configuration-managementSkill
- creating-providers-and-modulesSkill
- database-repository-patternSkill
- events-and-messagingSkill
- lexigram-uiSkill
- multimedia-generationSkill
- real-time-webSkill
- resilience-patternsSkill
- testing-with-lexigramSkill
- web-controllers-and-routingSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 83
Every exception has a _code attribute: LEX_ERR_<DOMAIN>_<NNN>.
- Distinctive: line 116
No exception defined in two places
- Distinctive: line 118
Every package needs a base exception class
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Using Result and Error Codes
Overview
Lexigram uses a two-track error strategy: Result[T, E] for expected domain failures, exceptions for unexpected infrastructure failures. Every exception carries a LEX_ERR_<DOMAIN>_<NNN> code.
Two-Track Strategy
Use Result[T, E] | Use Exceptions |
| User not found, validation failed | Database connection lost |
| Payment declined, permission denied | Network timeout, OOM |
| Business rule violation | Missing API key |
| LLM content filter triggered | Serialization bug |
Result API
from lexigram.result import Result, Ok, Err
from lexigram.result.utils import as_result, collect, partition
result = await service.find_user("123")
result.is_ok() / result.is_err()
result.unwrap() / result.unwrap_err() # only after is_ok/ is_err check
result.unwrap_or(default) / result.unwrap_or_else(fn)
# Sync transforms
result.map_sync(lambda u: u.email)
result.and_then_sync(validate_user)
# Async transforms
await result.map(load_profile)
await result.and_then(create_order)
# Exhaustive match
msg = result.match(
ok=lambda u: f"Found {u.name}",
err=lambda e: f"Error: {e}",
)
# Utils
result.expect("Should have found user")
result.to_optional()
result.inspect(lambda u: ...)
# Chaining helpers (lexigram.result.utils)
@as_result(ValueError, KeyError)
async def parse(data: str) -> int: ...
results = [Ok(1), Err("bad"), Ok(2)]
all_ok = collect(results) # Result[list[int], str]
oks, errs = partition(results) # ([1, 2], ["bad"])Prohibited Patterns
# ❌ Never unwrap() without checking
user = result.unwrap()
# ❌ Never wrap infrastructure errors in Result
try:
data = await db.query(sql)
except DatabaseError as e:
return Err(e) # Let exceptions propagate
# ❌ Never use Result for infallible operations
def add(a: int, b: int) -> Result[int, Never]:
return Ok(a + b)
# ❌ Never use Any as error type
async def execute() -> Result[SkillResult, Any]: ...Error Code System
Every exception has a _code attribute: LEX_ERR_<DOMAIN>_<NNN>.
Hundreds of registered codes across 40+ packages — see REF_ERROR_CODES.md.
Hierarchy
lexigram-contracts Extension Package
────────────────── ────────────────
LEX_ERR_AI_001 AIError LEX_ERR_LLM_002 LLMError(AIError)
LEX_ERR_LLM_003 LLMAuthenticationError(LLMError)
LEX_ERR_AGT_001 AgentError LEX_ERR_AGT_004 AgentConfigurationError(AgentError)
LEX_ERR_AGT_005 AgentExecutionError(AgentError)Creating New Exceptions
# Pick an UNUSED code in the domain's range (see docs/reference/REF_ERROR_CODES.md
# for taken codes). Codes are unique across the whole monorepo — e.g.
# LEX_ERR_CACHE_012 (LockAcquisitionError) and _013 (CacheSerializationError)
# are already taken.
class CacheCustomError(CacheError):
_code = "LEX_ERR_CACHE_020" # placeholder: use the actual next free number
"""Custom cache error."""Rules
- Base domain exceptions in
lexigram-contracts, leaf exceptions in extension packages - One definition per code across the entire monorepo
- No exception defined in two places
- Extensions extend contracts base (
class MyError(ContractsBaseError)) - Every package needs a base exception class
Domain Tags (68 domains)
Common tags: ADMIN (31), AGT (11), AUTH (28), CACHE (15), DB (11), DI (11), DOM (9), EVT (23), LLM (26), MCP (8), RAG (14), SEC (11), SQL (38), WF (22).
Common Mistakes
- Defining the same error code in two packages
- Using
Resultfor infrastructure failures (let them propagate) - Calling
unwrap()withoutis_ok()check - Returning
Resultfrom__init__or lifecycle hooks (boot,shutdown) - Using
Anyas the error type parameter
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

