Error Messages Guidelines
Purpose
This document establishes conventions for error messages to ensure consistency, clarity, and a better user experience.
Core Principles
- User-Focused: Write for API consumers, not developers
- Descriptive: State what is wrong, not what the system tried to do
- Actionable: When possible, hint at how to fix the issue
- Consistent: Follow the same patterns across the codebase
- Professional: Clear and respectful tone without being overly formal
Wording Guidelines
1. Voice and Tense
- Use present tense for describing the current state
- Use active voice instead of passive voice
- Be direct without unnecessary words
✅ Good: Entity urn:ngsi-ld:Device:001 does not exist\
❌ Avoid: Entity urn:ngsi-ld:Device:001 was not found\
❌ Avoid: The entity could not be found
2. Capitalization
- Use sentence case (capitalize only the first word and proper nouns)
- Do not use title case or all caps (except for acronyms like URI, JSON-LD)
✅ Good: Attribute temperature does not exist\
❌ Avoid: Attribute Temperature Does Not Exist\
❌ Avoid: ATTRIBUTE TEMPERATURE DOES NOT EXIST
3. Structure
Follow a consistent structure: Subject + Verb + Context
<Resource/Field> <verb> <additional context>
Examples:
- Entity {id} does not exist
- Attribute {name} is invalid
- Field 'expiresAt' must be in the future
- Type must be 'Subscription'
4. Terminology
Use consistent terminology across all messages:
| Concept | Use | Avoid |
|---|---|---|
| Non-existent resources | does not exist |
not found, could not find, missing |
| Already existing resources | already exists |
duplicate, exists already |
| Invalid values | is invalid |
is not valid, not correct |
| Required fields | is required |
must be present, shall be present |
| Type mismatches | must be {type} |
should be {type}, expected {type} |
| Value constraints | must be {constraint} |
should be {constraint}, needs to be {constraint} |
5. Avoid Technical Jargon
Replace internal/technical terms with user-friendly alternatives:
✅ Good: Type must be 'Subscription'\
❌ Avoid: type attribute must be equal to 'Subscription'
✅ Good: Subscription {id} already exists\
❌ Avoid: A subscription with id {id} already exists\
✅ Good: Field 'timeInterval' must be greater than zero\
❌ Avoid: The value of 'timeInterval' must be greater than zero (int)
6. Be Specific
Include relevant identifiers and context to help users diagnose the issue:
✅ Good: Entity urn:ngsi-ld:Device:001 does not exist\
❌ Avoid: Entity does not exist
✅ Good: Attribute temperature (datasetId: urn:ngsi-ld:Dataset:01) does not exist\
❌ Avoid: Attribute does not exist
7. Multiple Requirements
For validation with multiple alternatives:
✅ Good: At least one of 'entities' or 'watchedAttributes' is required\
❌ Avoid: At least one of entities or watchedAttributes shall be present
✅ Good: Field 'target' must specify either 'id', 'types', or 'scopes'\
❌ Avoid: You must specify a target id, types or scopes
8. Avoid Contractions and Informal Language
- Use full forms:
cannotinstead ofcan't,does notinstead ofdoesn't - Avoid informal pronouns like "you"
✅ Good: Field 'target' must specify either 'id', 'types', or 'scopes'\
❌ Avoid: You must specify a target id, types or scopes
✅ Good: Cannot specify both 'id' and 'types' in target\
❌ Avoid: You can't target an id and types or scopes
9. Authorization and Permission Errors
Use clear, consistent phrasing:
✅ Good: User is not authorized to access subscription {id}\
✅ Good: User is not authorized to modify entity {id}
❌ Avoid: User forbidden to modify entity\
❌ Avoid: Access denied to entity {id}
Code Reviewer Checklist
When reviewing code that introduces or modifies error messages, verify:
✅ Wording
- [ ] Uses present tense and active voice
- [ ] Uses sentence case (not title case or all caps)
- [ ] Follows the "Subject + Verb + Context" structure
- [ ] Uses consistent terminology (e.g., "does not exist" not "not found")
- [ ] Avoids technical jargon and internal terms
- [ ] Avoids informal language (no "you", "can't", etc.)
✅ Specificity
- [ ] Includes relevant identifiers (entity ID, attribute name, etc.)
- [ ] Provides enough context for debugging
- [ ] Is specific enough to be actionable
✅ Consistency
- [ ] Matches existing patterns for similar error types
- [ ] Uses the same phrasing as comparable messages
- [ ] Uses the appropriate exception type for the error category
✅ Centralization
- [ ] Message is not hardcoded in business logic
- [ ] Message is defined in
ErrorMessages.kt - [ ] No duplicate message definitions exist
✅ Correctness
- [ ] Message accurately describes the error condition
- [ ] Exception type matches the error category (BadRequestDataException, ResourceNotFoundException, etc.)
- [ ] Message is grammatically correct