Añadir 01-errores-comunes.md
529
01-errores-comunes.md.-.md
Normal file
529
01-errores-comunes.md.-.md
Normal file
@@ -0,0 +1,529 @@
|
||||
# Errores Comunes
|
||||
|
||||
Soluciones rápidas a los problemas más frecuentes.
|
||||
|
||||
---
|
||||
|
||||
## Backend (Python/FastAPI)
|
||||
|
||||
### Error: "Address already in use"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
ERROR: [Errno 48] error while attempting to bind on address ('0.0.0.0', 8000): address already in use
|
||||
```
|
||||
|
||||
**Causa:** El puerto 8000 ya está ocupado por otro proceso.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Opción 1: Matar el proceso en el puerto 8000
|
||||
# Linux/macOS:
|
||||
lsof -ti:8000 | xargs kill -9
|
||||
|
||||
# Windows:
|
||||
netstat -ano | findstr :8000
|
||||
taskkill /PID <PID> /F
|
||||
|
||||
# Opción 2: Usar otro puerto
|
||||
uvicorn app.main:app --reload --port 8001
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "No module named 'app'"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
ModuleNotFoundError: No module named 'app'
|
||||
```
|
||||
|
||||
**Causa:** Estás corriendo `uvicorn` desde la carpeta incorrecta.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Debes estar en basura_backend/
|
||||
cd basura_backend
|
||||
uvicorn app.main:app --reload
|
||||
|
||||
# NO corras desde basura_backend/app/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "table already exists"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
sqlite3.OperationalError: table users already exists
|
||||
```
|
||||
|
||||
**Causa:** La BD ya fue creada y el código intenta recrearla.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Borrar la BD y dejar que se recree
|
||||
rm basura.db
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "CORS policy" en Flutter
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Access to XMLHttpRequest at 'http://localhost:8000/eta/1' from origin 'http://localhost:...'
|
||||
has been blocked by CORS policy
|
||||
```
|
||||
|
||||
**Causa:** CORS no está habilitado en el backend.
|
||||
|
||||
**Solución:**
|
||||
```python
|
||||
# app/main.py
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"], # En desarrollo
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: WebSocket se cierra inmediatamente
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
WebSocket connection to 'ws://localhost:8000/ws/1' failed
|
||||
```
|
||||
|
||||
**Causa 1:** El `address_id` no existe en la BD.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Verificar que el address existe
|
||||
curl http://localhost:8000/eta/1
|
||||
|
||||
# Si da 404, usa otro address_id válido
|
||||
```
|
||||
|
||||
**Causa 2:** El simulador no está corriendo.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/admin/route/RUTA-01/start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Flutter
|
||||
|
||||
### Error: "Waiting for another flutter command to release the startup lock"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Waiting for another flutter command to release the startup lock...
|
||||
```
|
||||
|
||||
**Causa:** Hay un proceso de Flutter bloqueado.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Borrar el lock file
|
||||
rm ~/.dart_tool/dart_tool.lock
|
||||
|
||||
# Si persiste, reiniciar la terminal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Gradle build failed"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
FAILURE: Build failed with an exception.
|
||||
* What went wrong:
|
||||
Execution failed for task ':app:processDebugResources'.
|
||||
```
|
||||
|
||||
**Causa:** Java incorrecto o caché corrupta.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# 1. Verificar Java 17
|
||||
java -version
|
||||
|
||||
# 2. Limpiar build
|
||||
cd android
|
||||
./gradlew clean
|
||||
cd ..
|
||||
fvm flutter clean
|
||||
fvm flutter pub get
|
||||
|
||||
# 3. Rebuild
|
||||
fvm flutter run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Could not connect to WebSocket"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
WebSocketChannelException: WebSocketChannelException: SocketException:
|
||||
OS Error: Connection refused
|
||||
```
|
||||
|
||||
**Causa:** URL incorrecta o backend no está corriendo.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# 1. Verificar que el backend esté up
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# 2. Ajustar la URL según tu entorno:
|
||||
# Emulador Android:
|
||||
ws://10.0.2.2:8000/ws/1
|
||||
|
||||
# Emulador iOS:
|
||||
ws://localhost:8000/ws/1
|
||||
|
||||
# Dispositivo físico (reemplaza con tu IP):
|
||||
ws://192.168.1.10:8000/ws/1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "asset not found: assets/recycling_guide.json"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Unable to load asset: assets/recycling_guide.json
|
||||
```
|
||||
|
||||
**Causa:** El asset no está declarado en `pubspec.yaml`.
|
||||
|
||||
**Solución:**
|
||||
```yaml
|
||||
# pubspec.yaml
|
||||
flutter:
|
||||
assets:
|
||||
- assets/recycling_guide.json
|
||||
```
|
||||
|
||||
Luego:
|
||||
```bash
|
||||
fvm flutter clean
|
||||
fvm flutter pub get
|
||||
fvm flutter run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Unsupported class file major version 65"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Unsupported class file major version 65
|
||||
```
|
||||
|
||||
**Causa:** Estás usando Java 21 en lugar de Java 17.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Cambiar a Java 17
|
||||
# Linux:
|
||||
sudo apt install openjdk-17-jdk
|
||||
sudo update-alternatives --config java # selecciona 17
|
||||
|
||||
# macOS:
|
||||
brew install openjdk@17
|
||||
export JAVA_HOME=/usr/local/opt/openjdk@17
|
||||
|
||||
# Windows:
|
||||
# Desinstalar Java 21, instalar Java 17 desde adoptium.net
|
||||
|
||||
# Verificar
|
||||
java -version # debe mostrar "17.x.x"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "DioException: Connection timeout"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
DioException [connection timeout]: The connection has timed out
|
||||
```
|
||||
|
||||
**Causa:** Backend no responde o URL incorrecta.
|
||||
|
||||
**Solución:**
|
||||
```dart
|
||||
// Aumentar timeout
|
||||
final dio = Dio(BaseOptions(
|
||||
baseUrl: 'http://10.0.2.2:8000',
|
||||
connectTimeout: Duration(seconds: 10), // más tiempo
|
||||
receiveTimeout: Duration(seconds: 10),
|
||||
));
|
||||
```
|
||||
|
||||
O verificar que el backend esté corriendo:
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Bad state: Cannot add new events after calling close"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Bad state: Cannot add new events after calling close
|
||||
```
|
||||
|
||||
**Causa:** Intentas enviar datos a un Stream cerrado.
|
||||
|
||||
**Solución:**
|
||||
```dart
|
||||
class WSManager {
|
||||
final _controller = StreamController<Map<String, dynamic>>.broadcast();
|
||||
|
||||
void dispose() {
|
||||
if (!_controller.isClosed) {
|
||||
_controller.close();
|
||||
}
|
||||
}
|
||||
|
||||
void addEvent(Map<String, dynamic> event) {
|
||||
if (!_controller.isClosed) {
|
||||
_controller.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Git
|
||||
|
||||
### Error: "Merge conflict"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
CONFLICT (content): Merge conflict in lib/main.dart
|
||||
```
|
||||
|
||||
**Causa:** Dos personas editaron el mismo archivo.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# 1. Abrir el archivo con conflicto
|
||||
# Verás marcadores:
|
||||
<<<<<<< HEAD
|
||||
código de tu rama
|
||||
=======
|
||||
código de la otra rama
|
||||
>>>>>>> feature/otra-persona
|
||||
|
||||
# 2. Resolver manualmente: quedarte con uno, combinar, o reescribir
|
||||
|
||||
# 3. Agregar el archivo resuelto
|
||||
git add lib/main.dart
|
||||
|
||||
# 4. Completar el merge
|
||||
git commit -m "Resuelto conflicto en main.dart"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Your branch has diverged"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
Your branch and 'origin/dev' have diverged,
|
||||
and have 3 and 2 different commits each, respectively.
|
||||
```
|
||||
|
||||
**Causa:** Tu rama local y la remota tienen commits diferentes.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Opción 1: Pull con rebase (preferido)
|
||||
git pull --rebase origin dev
|
||||
|
||||
# Opción 2: Merge
|
||||
git pull origin dev
|
||||
|
||||
# Resolver conflictos si los hay
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Permission denied (publickey)"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
git@git.onlinces.net: Permission denied (publickey).
|
||||
```
|
||||
|
||||
**Causa:** No tienes SSH configurado.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Usar HTTPS en lugar de SSH
|
||||
git remote set-url origin https://git.onlinces.net/onlinces/hackathon-...
|
||||
|
||||
# O configurar SSH keys (más complejo, no recomendado para hackathon)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Riverpod
|
||||
|
||||
### Error: "ProviderNotFoundException"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
ProviderNotFoundException: Error: Could not find the correct Provider
|
||||
```
|
||||
|
||||
**Causa:** Falta el `ProviderScope` en la raíz de la app.
|
||||
|
||||
**Solución:**
|
||||
```dart
|
||||
// main.dart
|
||||
void main() {
|
||||
runApp(
|
||||
ProviderScope( // ← debe estar aquí
|
||||
child: MyApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "The provider returned null"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
StateError: The provider returned null
|
||||
```
|
||||
|
||||
**Causa:** Un provider devolvió `null` cuando debía devolver un valor.
|
||||
|
||||
**Solución:**
|
||||
```dart
|
||||
// Opción 1: Devolver un valor por defecto
|
||||
final myProvider = Provider<String>((ref) {
|
||||
return 'valor por defecto'; // nunca null
|
||||
});
|
||||
|
||||
// Opción 2: Usar Provider.autoDispose si es temporal
|
||||
final myProvider = Provider.autoDispose<String?>((ref) {
|
||||
return null; // OK si es nullable
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de red
|
||||
|
||||
### Backend en PC, Flutter en dispositivo físico
|
||||
|
||||
**Síntoma:** Flutter no puede conectar al backend.
|
||||
|
||||
**Causa:** `localhost` no funciona desde un dispositivo externo.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# 1. Obtener la IP de tu PC
|
||||
# Linux/macOS:
|
||||
ifconfig | grep inet
|
||||
|
||||
# Windows:
|
||||
ipconfig
|
||||
|
||||
# Busca algo como 192.168.1.10
|
||||
|
||||
# 2. Asegúrate que el backend escuche en 0.0.0.0 (no 127.0.0.1)
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||
|
||||
# 3. En Flutter, usa la IP de tu PC
|
||||
const baseUrl = 'http://192.168.1.10:8000';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Firewall bloquea conexiones
|
||||
|
||||
**Síntoma:** Dispositivo físico no puede conectar, pero emulador sí.
|
||||
|
||||
**Causa:** El firewall de tu PC bloquea el puerto 8000.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Linux (UFW):
|
||||
sudo ufw allow 8000/tcp
|
||||
|
||||
# macOS:
|
||||
# System Preferences → Security & Privacy → Firewall → Firewall Options
|
||||
# Permitir conexiones entrantes para Python
|
||||
|
||||
# Windows:
|
||||
# Panel de control → Firewall de Windows → Configuración avanzada
|
||||
# Regla de entrada → Puerto 8000 TCP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Base de datos
|
||||
|
||||
### Error: "database is locked"
|
||||
|
||||
**Síntoma:**
|
||||
```
|
||||
sqlite3.OperationalError: database is locked
|
||||
```
|
||||
|
||||
**Causa:** Otro proceso está usando `basura.db`.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Cerrar todos los procesos que usen la BD
|
||||
# Incluye: DB Browser, sqlite3 cli, uvicorn
|
||||
|
||||
# Reiniciar uvicorn
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Datos del seed no aparecen
|
||||
|
||||
**Síntoma:** La BD está creada pero vacía.
|
||||
|
||||
**Causa:** El seed falló silenciosamente.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Borrar BD y recrear con logs
|
||||
rm basura.db
|
||||
uvicorn app.main:app --reload --log-level debug
|
||||
|
||||
# Verificar que aparezca:
|
||||
# "INFO: Seed de demo creado: RUTA-01 con 5 waypoints"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Siguiente paso
|
||||
|
||||
- [Problemas de versiones](02-versiones.md) — Dart SDK, Flutter, Java
|
||||
- [Debug del simulador](03-debug-simulador.md) — verificar estado del camión
|
||||
Reference in New Issue
Block a user