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