mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-10 13:12:49 +02:00
Upload files to "docs"
This commit is contained in:
parent
3b1a01045f
commit
d85ab0cbdb
3 changed files with 378 additions and 0 deletions
102
docs/enhanced_api_guide.md
Normal file
102
docs/enhanced_api_guide.md
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# Enhanced API Guide for Continuwuity
|
||||||
|
|
||||||
|
This guide provides comprehensive documentation for using our enhanced types and error handling in Continuwuity applications.
|
||||||
|
|
||||||
|
## Enhanced Error Handling
|
||||||
|
|
||||||
|
Our enhanced error system provides better user experience and debugging capabilities.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
|
||||||
|
- **User-friendly messages**: Clear, actionable error messages for users
|
||||||
|
- **Sanitized logging**: Safe error messages for logs without sensitive data
|
||||||
|
- **Matrix compliance**: Proper Matrix error codes and HTTP status codes
|
||||||
|
- **Contextual information**: Rich error context for better debugging
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
#### Creating Errors
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use conduwuit_core::error::*;
|
||||||
|
|
||||||
|
// Authentication errors
|
||||||
|
let auth_error = EnhancedError::AuthenticationError {
|
||||||
|
message: "Invalid token".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Room errors
|
||||||
|
let room_error = EnhancedError::RoomNotFoundError {
|
||||||
|
room_id: "!room123:example.com".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
// User errors
|
||||||
|
let user_error = EnhancedError::UserNotFoundError {
|
||||||
|
user_id: "@user:example.com".to_string()
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Error Handling
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use conduwuit_core::error::*;
|
||||||
|
|
||||||
|
fn handle_error(error: &EnhancedError) -> Result<(), String> {
|
||||||
|
match error {
|
||||||
|
EnhancedError::AuthenticationError { message } => {
|
||||||
|
tracing::error!("Authentication failed: {}", message);
|
||||||
|
Err("Please check your login credentials and try again.".to_string())
|
||||||
|
},
|
||||||
|
EnhancedError::RoomNotFoundError { room_id } => {
|
||||||
|
tracing::warn!("Room not found: {}", room_id);
|
||||||
|
Err(format!("The room '{}' could not be found.", room_id))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
tracing::error!("Unexpected error: {}", error);
|
||||||
|
Err("An unexpected error occurred. Please try again.".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enhanced Type Definitions
|
||||||
|
|
||||||
|
Our enhanced types provide cleaner, more focused structures for Matrix operations.
|
||||||
|
|
||||||
|
### Room Management
|
||||||
|
|
||||||
|
#### EnhancedRoomInfo
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use conduwuit_core::types_enhanced::*;
|
||||||
|
|
||||||
|
// Create room info
|
||||||
|
let room_info = EnhancedRoomInfo {
|
||||||
|
room_id: room_id!("!test:matrix.org").to_owned(),
|
||||||
|
name: Some("Test Room".to_string()),
|
||||||
|
topic: Some("A test room for development".to_string()),
|
||||||
|
creator: user_id!("@creator:matrix.org").to_owned(),
|
||||||
|
member_count: 5,
|
||||||
|
join_rule: JoinRule::Public,
|
||||||
|
power_levels: create_default_power_levels(),
|
||||||
|
creation_content: RoomCreateEventContent::new(user_id!("@creator:matrix.org").to_owned()),
|
||||||
|
is_direct: false,
|
||||||
|
notification_count: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check permissions
|
||||||
|
if room_info.is_admin(&user_id!("@admin:matrix.org")) {
|
||||||
|
println!("User is an admin");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Always use enhanced error types** for better user experience
|
||||||
|
2. **Provide contextual information** in error messages
|
||||||
|
3. **Use proper Matrix error codes** for federation compatibility
|
||||||
|
4. **Sanitize error messages** before logging to prevent data leaks
|
||||||
|
5. **Leverage enhanced types** for cleaner, more maintainable code
|
||||||
|
6. **Test error scenarios** to ensure proper error handling
|
||||||
|
|
||||||
|
This enhanced API provides a more robust, user-friendly, and maintainable foundation for Continuwuity applications.
|
148
docs/enhanced_best_practices.md
Normal file
148
docs/enhanced_best_practices.md
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
# Enhanced Best Practices for Continuwuity
|
||||||
|
|
||||||
|
This document outlines best practices for using our enhanced error handling and type definitions in Continuwuity applications.
|
||||||
|
|
||||||
|
## Error Handling Best Practices
|
||||||
|
|
||||||
|
### 1. Use Enhanced Error Types
|
||||||
|
|
||||||
|
Always prefer enhanced error types over generic errors for better user experience:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ Good
|
||||||
|
let error = EnhancedError::RoomNotFoundError {
|
||||||
|
room_id: "!room123:example.com".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
// ❌ Avoid
|
||||||
|
let error = Error::BadRequest(ErrorKind::NotFound, "Room not found");
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Provide Contextual Information
|
||||||
|
|
||||||
|
Include relevant context in error messages:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ Good
|
||||||
|
let error = EnhancedError::InsufficientPermissionsError {
|
||||||
|
user_id: "@user:example.com".to_string(),
|
||||||
|
message: "Admin role required for this operation".to_string()
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Sanitize Error Messages for Logging
|
||||||
|
|
||||||
|
Always sanitize error messages before logging to prevent data leaks:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ Good
|
||||||
|
tracing::error!("Database operation failed: {}", error.sanitized_message());
|
||||||
|
```
|
||||||
|
|
||||||
|
## Type Definition Best Practices
|
||||||
|
|
||||||
|
### 1. Use Enhanced Types for Better Structure
|
||||||
|
|
||||||
|
Prefer enhanced types over basic types for complex operations:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ Good
|
||||||
|
let room_info = EnhancedRoomInfo {
|
||||||
|
room_id: room_id!("!room123:example.com").to_owned(),
|
||||||
|
name: Some("Test Room".to_string()),
|
||||||
|
// ... other fields
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Leverage Built-in Methods
|
||||||
|
|
||||||
|
Use the built-in methods provided by enhanced types:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ✅ Good
|
||||||
|
if room_info.is_admin(&user_id) {
|
||||||
|
// Admin operations
|
||||||
|
}
|
||||||
|
|
||||||
|
if room_info.can_send_message(&user_id) {
|
||||||
|
// Send message
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Design Best Practices
|
||||||
|
|
||||||
|
### 1. Consistent Error Responses
|
||||||
|
|
||||||
|
Ensure all API endpoints return consistent error responses:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
async fn api_endpoint() -> Result<Json<Response>, (StatusCode, Json<serde_json::Value>)> {
|
||||||
|
match operation() {
|
||||||
|
Ok(response) => Ok(Json(response)),
|
||||||
|
Err(error) => {
|
||||||
|
let enhanced_error = match error {
|
||||||
|
SomeError::NotFound => EnhancedError::RoomNotFoundError {
|
||||||
|
room_id: "unknown".to_string()
|
||||||
|
},
|
||||||
|
_ => EnhancedError::InternalServerError {
|
||||||
|
message: "Unexpected error".to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Err((
|
||||||
|
StatusCode::from_u16(enhanced_error.http_status_code()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
|
||||||
|
Json(serde_json::json!({
|
||||||
|
"errcode": enhanced_error.matrix_error_code(),
|
||||||
|
"error": enhanced_error.user_message()
|
||||||
|
}))
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Best Practices
|
||||||
|
|
||||||
|
### 1. Test Error Scenarios
|
||||||
|
|
||||||
|
Always test error scenarios to ensure proper error handling:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_not_found_error() {
|
||||||
|
let error = EnhancedError::RoomNotFoundError {
|
||||||
|
room_id: "!test:matrix.org".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(error.matrix_error_code(), "M_NOT_FOUND");
|
||||||
|
assert_eq!(error.http_status_code(), 404);
|
||||||
|
assert!(error.user_message().contains("could not be found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
### 1. Validate Permissions
|
||||||
|
|
||||||
|
Always validate permissions before performing operations:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn delete_room(room_info: &EnhancedRoomInfo, user_id: &OwnedUserId) -> Result<(), EnhancedError> {
|
||||||
|
if !room_info.is_admin(user_id) {
|
||||||
|
return Err(EnhancedError::InsufficientPermissionsError {
|
||||||
|
user_id: user_id.to_string(),
|
||||||
|
message: "Admin role required to delete rooms".to_string()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proceed with deletion
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Following these best practices will help you build more robust, secure, and maintainable Continuwuity applications.
|
128
docs/enhanced_examples.md
Normal file
128
docs/enhanced_examples.md
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
# Enhanced Examples for Continuwuity
|
||||||
|
|
||||||
|
This document provides practical examples of using our enhanced error handling and type definitions in Continuwuity applications.
|
||||||
|
|
||||||
|
## Basic Error Handling Examples
|
||||||
|
|
||||||
|
### Authentication Error Handling
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use conduwuit_core::error::*;
|
||||||
|
|
||||||
|
async fn authenticate_user(token: &str) -> Result<UserId, EnhancedError> {
|
||||||
|
if token.is_empty() {
|
||||||
|
return Err(EnhancedError::AuthenticationError {
|
||||||
|
message: "Token is required".to_string()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if token == "invalid" {
|
||||||
|
return Err(EnhancedError::AuthenticationError {
|
||||||
|
message: "Invalid token provided".to_string()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(user_id!("@user:example.com"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Room Management Examples
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use conduwuit_core::types_enhanced::*;
|
||||||
|
use conduwuit_core::error::*;
|
||||||
|
|
||||||
|
async fn get_room_info(room_id_str: &str) -> Result<EnhancedRoomInfo, EnhancedError> {
|
||||||
|
let room_id = room_id_str.parse::<OwnedRoomId>()
|
||||||
|
.map_err(|_| EnhancedError::ValidationError {
|
||||||
|
field: "room_id".to_string(),
|
||||||
|
message: "Invalid room ID format".to_string()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if room_id_str == "!nonexistent:example.com" {
|
||||||
|
return Err(EnhancedError::RoomNotFoundError {
|
||||||
|
room_id: room_id_str.to_string()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EnhancedRoomInfo {
|
||||||
|
room_id: room_id.clone(),
|
||||||
|
name: Some("Example Room".to_string()),
|
||||||
|
topic: Some("A room for examples".to_string()),
|
||||||
|
creator: user_id!("@creator:example.com").to_owned(),
|
||||||
|
member_count: 5,
|
||||||
|
join_rule: JoinRule::Public,
|
||||||
|
power_levels: create_default_power_levels(),
|
||||||
|
creation_content: RoomCreateEventContent::new(user_id!("@creator:example.com").to_owned()),
|
||||||
|
is_direct: false,
|
||||||
|
notification_count: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Endpoint Examples
|
||||||
|
|
||||||
|
### Room Information Endpoint
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use axum::extract::Path;
|
||||||
|
use axum::response::Json;
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use conduwuit_core::error::*;
|
||||||
|
use conduwuit_core::types_enhanced::*;
|
||||||
|
|
||||||
|
async fn get_room_endpoint(
|
||||||
|
Path(room_id): Path<String>
|
||||||
|
) -> Result<Json<EnhancedRoomInfo>, (StatusCode, Json<serde_json::Value>)> {
|
||||||
|
match get_room_info(&room_id).await {
|
||||||
|
Ok(room_info) => Ok(Json(room_info)),
|
||||||
|
Err(error) => {
|
||||||
|
let status_code = StatusCode::from_u16(error.http_status_code())
|
||||||
|
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
let error_response = serde_json::json!({
|
||||||
|
"errcode": error.matrix_error_code(),
|
||||||
|
"error": error.user_message()
|
||||||
|
});
|
||||||
|
|
||||||
|
Err((status_code, Json(error_response)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Examples
|
||||||
|
|
||||||
|
### Unit Test Examples
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_authenticate_user_success() {
|
||||||
|
let result = authenticate_user("valid_token").await;
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_authenticate_user_invalid_token() {
|
||||||
|
let result = authenticate_user("invalid").await;
|
||||||
|
assert!(matches!(result, Err(EnhancedError::AuthenticationError { .. })));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_room_info_permissions() {
|
||||||
|
let room_info = create_test_room_info();
|
||||||
|
let admin_id = user_id!("@admin:example.com");
|
||||||
|
let user_id = user_id!("@user:example.com");
|
||||||
|
|
||||||
|
assert!(room_info.is_admin(&admin_id));
|
||||||
|
assert!(!room_info.is_admin(&user_id));
|
||||||
|
assert!(room_info.can_send_message(&user_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These examples demonstrate how to effectively use our enhanced error handling and type definitions in real Continuwuity applications.
|
Loading…
Add table
Add a link
Reference in a new issue