serviceerr

package
v0.0.1-beta.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: AGPL-3.0 Imports: 2 Imported by: 0

Documentation

Overview

Package serviceerr 定义 service 层错误哨兵(单一真相)。

叶子包(零内部依赖):不 import internal/service 或任何上层包,否则形成 service → 本包 → service 的 import 环。service 包以别名 re-export (var ErrNotFound = serviceerr.ErrNotFound 等)保持既有引用 (errors.Is(err, service.ErrXxx))同一哨兵实例语义——80+ 调用点零改动。

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound     = errors.New("service: not found")
	ErrInvalidInput = errors.New("service: invalid input")
	ErrConflict     = errors.New("service: conflict")
	// ErrEmailExists 邮箱已被注册(自助注册 RegisterUser / 管理面 CreateUser)→
	// 409。独立哨兵:Error() 面向客户端可读、刻意不含内部 "service: " 前缀;
	// Unwrap 到 ErrConflict,故 httpface 的 409 映射与 errors.Is(err, ErrConflict)
	// 判定均不变——仅把响应文案从裸哨兵换成清晰原因("email already registered")。
	ErrEmailExists error = emailExistsError{}
	// ErrPreconditionFailed 乐观锁前置条件不满足(PATCH 的 If-Match 陈旧 → 412)。
	// 与 ErrConflict(body-CAS 陈旧 → 409,仅 recover 的 expected_revision)刻意
	// 分码:header 前置条件与 body-CAS 是两类不同的陈旧判据。
	ErrPreconditionFailed = errors.New("service: precondition failed")
	// ErrForbidden 授权复核失败(spec 2026-10-09 §6.5 I5:静态 admin token / 写事务内
	// 操作者 status/role/token_version 复核不通过 ⇒ 403)。
	ErrForbidden             = errors.New("service: forbidden")
	ErrInvalidCredentials    = errors.New("service: invalid email or password")
	ErrSignupDisabled        = errors.New("service: signup disabled")
	ErrTooManyRequests       = errors.New("service: too many requests")
	ErrMailNotConfigured     = errors.New("service: mail not configured")
	ErrMailQueueFull         = errors.New("service: mail queue full")
	ErrMailChannelTestFailed = errors.New("service: mail channel test failed")
)

Functions

This section is empty.

Types

type StatsWindowError

type StatsWindowError struct {
	domain.StatsWindowError
}

StatsWindowError 统计窗口拒绝的**线缆载体**(spec §4.4(d):一个哨兵 + 一个 载体类型):判定属 domain.Admit(本类型不做任何判定),它只把该判定接到既有 校验哨兵上——httpface 的 400 映射按哨兵判,语义与引入前完全一致——并携带 §4.4(c) 的机读字段(httpface 用 errors.As 取值,**禁字符串嗅探**)。

**位置**:本类型必须同时对生产方(internal/service)与序列化方 (internal/handler/httpface)可见,而 httpface **不能** import internal/service:service → internal/auth → handler/httpface 已成环 (internal/auth/middleware.go 用 httpface 写错误响应)。故载体落在本叶子包, service 以类型别名 re-export(与 ErrXxx 哨兵同一手法、同一理由),调用点仍 写 service.StatsWindowError;这是位置选择,不是第二套类型。

func (*StatsWindowError) CarriesWindowFields

func (e *StatsWindowError) CarriesWindowFields() bool

CarriesWindowFields 该拒绝是否携带 storage / limit_seconds / retention_days / effective_* 字段。**白名单**(fail-closed):只有真正知道"实际存储/上限/截止/ 生效窗口"的判定才携带——新增拒绝原因默认不携带,绝不自带伪造事实。 不带的两类都是"参数本身非法"(`window_invalid`:必填/倒序/时长串不可解析; `window_ambiguous`:from/to/window 未恰择一):它们没有判定出的存储、上限、 截止或生效窗口——把被拒的请求窗口回显成生效窗口就是伪造事实(J2b)。

func (*StatsWindowError) Unwrap

func (e *StatsWindowError) Unwrap() error

Unwrap 拒绝一律映射既有校验哨兵:errors.Is(err, ErrInvalidInput) 恒成立 (400 映射的唯一依据,语义与此前各校验 helper 的哨兵一致)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL