
Spec
Enum and Error Extension User Manual
Add business codes, multi-language messages, and error metadata to enum values.
Extension Package: apihug/protobuf/extend/constant.proto
Scope: EnumValue
Scenarios: Business enums, error codes
NEVER add any file-level option declarations in proto files:
// ❌ Forbidden to use the following options (rely on default code generation configuration)
option java_package = "...";
option java_multiple_files = true;
option go_package = "...";
All code generation configurations are automatically managed by the build system. Strictly forbidden to manually add any file-level options.
import "apihug/protobuf/extend/constant.proto";
ENUM_NAME = sequence [(hope.constant.field) = {
code: business_code; // int32
message: "English"; // string
message2: "Chinese"; // string
}];
syntax = "proto3";
package com.example.order;
import "apihug/protobuf/extend/constant.proto";
enum OrderStatusEnum {
PLACED = 0 [(hope.constant.field) = {
code: 1,
message: "Placed",
message2: "已经下单"
}];
APPROVED = 1 [(hope.constant.field) = {
code: 2,
message: "Approved",
message2: "已经审批"
}];
DELIVERED = 2 [(hope.constant.field) = {
code: 4,
message: "Delivered",
message2: "已经发货"
}];
}
| Field | Type | Required | Description |
|---|---|---|---|
code | int32 | Yes | Business code, unique within the same enum |
message | string | Yes | Primary language message (English), defaults to enum name |
message2 | string | No | Secondary language message (Chinese) |
error | Error message | No | Error extension info (only for error codes) |
Note: cn_message (field=3) was deprecated on 2024-05-08, please use message2
error: {
title: "Error title"; // string
tips: "Handling tips"; // string
http_status: HTTP status enum; // Enum name (NOT_FOUND)
phase: Layer enum; // CONTROLLER/SERVICE/DOMAIN
severity: Severity enum; // LOW/WARN/ERROR/FATAL
}
import "apihug/protobuf/extend/constant.proto";
enum UserError {
USER_NOT_FOUND = 1 [(hope.constant.field) = {
code: 10001,
message: "user_not_found",
message2: "用户不存在"
error: {
title: "User Not Found",
tips: "检查用户ID是否正确",
http_status: NOT_FOUND, // ❌ Don't write 404
phase: SERVICE,
severity: ERROR
}
}];
}
| Field | Type | Values | Description |
|---|---|---|---|
title | string | - | Error title |
tips | string | - | Handling suggestion |
http_status | HttpStatus enum | NOT_FOUND/BAD_REQUEST/… | HTTP status code (write enum name) |
phase | Phase enum | CONTROLLER/SERVICE/DOMAIN | Error layer |
severity | Severity enum | LOW/WARN/ERROR/FATAL | Severity level |
HttpStatus Common Values: BAD_REQUEST(400) | UNAUTHORIZED(401) | FORBIDDEN(403) | NOT_FOUND(404) | CONFLICT(409) | INTERNAL_SERVER_ERROR(500)
Phase: CONTROLLER(form layer) | SERVICE(service layer) | DOMAIN(domain layer)
Severity: LOW(no impact) | WARN(retryable) | ERROR(business interrupted) | FATAL(data corruption)
| Syntax | Type | Wrong Example | Correct Example |
|---|---|---|---|
code | int32 | - | code: 10001 |
message | string | - | message: "user_not_found" |
http_status | enum | ❌ http_status: 404 | ✅ http_status: NOT_FOUND |
phase | enum | ❌ phase: "SERVICE" | ✅ phase: SERVICE |
severity | enum | ❌ severity: 2 | ✅ severity: ERROR |
syntax = "proto3";
package com.example.user;
import "apihug/protobuf/extend/constant.proto";
import "apihug/protobuf/swagger/annotations.proto";
// Authority enum
enum Authority {
option (hope.swagger.enm) = {
title: "Authority enum";
description: "System permissions";
};
USER_CREATE = 0 [(hope.constant.field) = {
code: 1001,
message: "user:create",
message2: "创建用户"
}];
USER_DELETE = 1 [(hope.constant.field) = {
code: 1002,
message: "user:delete",
message2: "删除用户"
}];
}
// Error code enum
enum UserError {
USER_NOT_FOUND = 0 [(hope.constant.field) = {
code: 10001,
message: "user_not_found",
message2: "用户不存在"
error: {
title: "User Not Found",
tips: "检查用户ID是否正确",
http_status: NOT_FOUND,
phase: SERVICE,
severity: ERROR
}
}];
PASSWORD_INVALID = 1 [(hope.constant.field) = {
code: 10002,
message: "password_invalid",
message2: "密码错误"
error: {
title: "Invalid Password",
tips: "密码错误次数过多将锁定账户",
http_status: UNAUTHORIZED,
phase: CONTROLLER,
severity: WARN
}
}];
}
❌ Wrong:
error: {
http_status: 404, // Don't write numbers
phase: "SERVICE", // Don't add quotes
severity: 2 // Don't write sequence numbers
}
✅ Correct:
error: {
http_status: NOT_FOUND, // Enum name
phase: SERVICE,
severity: ERROR
}
❌ Wrong:
enum UserError {
ERROR_1 = 0 [(hope.constant.field) = {code: 10001}];
ERROR_2 = 1 [(hope.constant.field) = {code: 10001}]; // Duplicate code
}
✅ Correct:
enum UserError {
ERROR_1 = 0 [(hope.constant.field) = {code: 10001}];
ERROR_2 = 1 [(hope.constant.field) = {code: 10002}]; // Unique code
}
syntax = "proto3";
package your_package_name;
import "apihug/protobuf/extend/constant.proto";
enum EnumName {
VALUE_NAME = sequence [(hope.constant.field) = {
code: business_code,
message: "English",
message2: "Chinese"
}];
}
enum ErrorEnumName {
ERROR_NAME = sequence [(hope.constant.field) = {
code: error_code,
message: "identifier",
message2: "Chinese description"
error: {
title: "Title",
tips: "Tips",
http_status: HTTP_STATUS,
phase: PHASE,
severity: SEVERITY
}
}];
}