Overview
Troubleshooting & Best Practices
Questa pagina raccoglie i sintomi piu' frequenti su un'installazione WUIC, la causa reale e il rimedio verificato. Prima di cercare nel codice leggi i tre endpoint diagnostici: nella maggior parte dei casi la risposta e' li'.
Prima diagnosi: tre endpoint
| Endpoint | Cosa dice | Campi da guardare |
|---|---|---|
GET /api/Meta/LicenseStatus | stato licenza e fingerprint della macchina | licenseValid, licenseReason, tier, features, machineFingerprint, dataDbms, metaDbms |
GET /api/Meta/FirstRunStatus | se l'installazione e' ancora in first-run | firstRun |
GET /api/Rag/Health | stato dell'engine RAG .NET | status (ok / not-initialized), engine, lastError |
Sintomi frequenti
Le liste mostrano al massimo 20 record
Il backend gira in modalita' Trial: licenza assente, scaduta o con fingerprint non autorizzato. LicenseStatus risponde licenseValid=false con il motivo in licenseReason (invalid_signature, machine_fingerprint_not_authorized, machine_fingerprint_missing, license_expired). Rimedio: pagina Licensing; dopo aver inserito license-payload e license-signature riavvia il backend e ricontrolla licenseValid=true.
Una feature Pro apre la pagina "accesso negato"
Il tier della licenza non include la feature (features in LicenseStatus): designer, workflow, report, spreadsheet, pivot-grid e RAG chatbot sono Professional. Il guard requireFeature della route blocca l'accesso con Developer.
"Server RAG non raggiungibile" / RAG offline
status=not-initializedsenzalastError: l'engine sta scaricando modelli e indice (~4,5 GB, 1-5 min) o li sta caricando (warm-up ~30 s). Attendi la notifica in-app.lastErrorvalorizzato: download fallito (CDN non raggiungibile, disco pieno) oppurerag-engine/WuicRagEngine.dllmancante. Controllarag-engine-models-url, lo spazio disco erag-engine-dll-path.rag-use-dotnet-engine=falsesenza server Python: il controller fa da bridge verso127.0.0.1:8765, che non esiste. Riporta la chiave atrue.- Query lente (15-25 s): normale su CPU. Con GPU NVIDIA verifica CUDA 12.x + cuDNN 9 e
rag-engine-cuda-path. - Cold start lento su Windows: aggiungi
rag-engine/artifacts/alle esclusioni dell'antivirus (Defender scansionavectors.npya ogni avvio).
Le modifiche ai metadata non si vedono
La cache runtime dei metadata e' ancora valida. Dopo modifiche dirette in SQL alle tabelle _metadati__* chiama MetaService.invalidateMetadataRuntime con body esplicito {"clearAll":true} (senza body il flush e' parziale) e verifica che projectMetadataVersion cambi con MetaService.getProjectMetadataVersion. Le modifiche fatte dal designer o dal chatbot invalidano da sole.
Ogni query piu' lunga di pochi secondi fallisce
AppSettings.autoGeneratedQueryTimeout e' il timeout in secondi delle query autogenerate: un valore troppo basso (es. 1) fa fallire qualunque lista non banale. Riportalo a 30 o piu'; la chiave e' hot-reload.
"Errore concorrenza ottimistica" in salvataggio
Il record e' stato modificato da un altro utente o processo dopo la lettura: ricarica e riapplica la modifica. Se compare su tutte le scritture, controlla che non ci siano due backend sullo stesso database (tipico in test: uno lanciato a mano piu' quello del dispatcher). Vedi Concorrenza ottimistica.
La sessione viene chiusa da sola (session_replaced)
Il framework applica la sessione singola per utente: un secondo login dello stesso utente sostituisce il primo. Se succede senza un secondo login, di nuovo: due backend sullo stesso DB metadata.
Il wizard di first-run riappare a ogni avvio
AppSettings.firstRun e' ancora "true" nel file appsettings.{Environment}.json letto dall'host in esecuzione (attenzione all'ambiente attivo: Development vs Production). Il wizard lo porta a false a fine provisioning; se il file non e' scrivibile dal processo, resta true.
Un lookup mostra [object Object]
mcuilookupdata_value_field, mcuilookupdata_text_field e mc_ui_grid_*_id_field devono contenere il nome friendly della colonna (= mc_nome_colonna): sono chiavi di accesso al JSON della response. I campi che emettono SQL (md_nome_tabella, mc_real_column_name) devono invece avere il case fisico esatto dello schema.
Il filtro in query string viene ignorato
Le URL verso <route>/List accettano filterInfo=..., non filter=....
Route con spazi non trovate
Le route metadata possono contenere spazi significativi: non applicare trim() o normalizzazioni quando le costruisci o le confronti.
Errore 10316 durante lo scaffolding del tutorial
SQL Server 2017, o Express con il cap RAM, sotto carico spatial. Requisito: SQL Server 2019+; per il dev locale Developer Edition o LocalDB.
Linux dietro reverse proxy: URL con porta o schema sbagliati
Il vhost nginx deve inoltrare host e schema: proxy_set_header Host $http_host; e proxy_set_header X-Forwarded-Proto $scheme;. Gli upgrade non riscrivono un vhost esistente.
Linux: connessioni rifiutate con centinaia di utenti
Con i default di nginx e dei database (nginx 768 connessioni per worker, MySQL 151 connessioni, PostgreSQL 100, Oracle Free 200 processi) il server rifiuta connessioni prima che l'applicazione sia carica: nell'error.log di nginx compare worker_connections are not enough, nel log dell'applicazione Too many connections (MySQL), 53300: sorry, too many clients already (PostgreSQL) oppure ORA-12516 / ORA-00020 (Oracle). L'installer Linux alza questi limiti: nginx 4096 connessioni per worker con keep-alive verso Kestrel, MySQL e PostgreSQL 300 connessioni e buffer al 25% della RAM, Oracle 400 processi. Un'installazione fatta con un installer precedente mantiene i vecchi valori: i comandi per alzarli a mano sono in scripts/linux/README.md, sezione "Capacity for hundreds of concurrent users". SQL Server Express resta limitato a 4 core e circa 1,4 GB di buffer pool, qualunque sia il server.
Report non generati su Linux
Le versioni precedenti alla 1.7.0 gestivano i font con una libreria disponibile solo su Windows: aggiorna il pacchetto.
Login rifiutato dopo molti tentativi (HTTP 429)
Il login risponde 429 errors.auth.login_rate_limited: e' scattato il limite dei tentativi di login, e retryAfterSeconds dice quanti secondi aspettare. Le cause sono due:
- Stesso utente: 5 password sbagliate in 5 minuti bloccano quell'utente per 1 minuto. Aspetta il minuto; un login riuscito azzera il contatore. Questo limite non si spegne.
- Molti login dallo stesso IP (stress test, ufficio dietro un NAT condiviso): scatta solo se
loginRateLimitPerIpPerMinutee' maggiore di0, e blocca l'IP per 1 minuto. Alza il valore, oppure aggiungi l'IP aloginRateLimitExemptIps(es.10.0.2.2per una VM VirtualBox in NAT, che vede l'host con quell'indirizzo). Fino alla 1.7.15 il limite per IP era fisso a 30 tentativi al minuto e l'unica eccezione era il loopback.
Vedi Autenticazione & Autorizzazioni.
Checklist rapida
1. Network tab: request e response del MetaService.* che fallisce. Una chiave JSON sbagliata non ritorna 400: il backend usa i default e la diagnosi viene falsata.
2. md_props_bag della route e configurazione colonne (mc_ui_column_type, lookup, flag hide).
3. LicenseStatus, FirstRunStatus, Rag/Health come sopra.
4. appsettings.{Environment}.json dell'ambiente effettivamente attivo.
5. Un solo backend per database.
Best practice
- Chiavi primarie e indici sulle tabelle esposte: filtri, paginazione e ordinamento autogenerati li usano.
- Modifica i metadata dal designer o dal chatbot quando puoi: l'invalidazione della cache e' automatica.
- Abilita
AppSettings:enablePerformanceInspectorper misurare fetch e render per route (media, p95, massimo) prima di ottimizzare a intuito. - Dopo un upgrade confronta
appsettings.jsoncon il template del pacchetto: le nuove chiavi hanno default conservativi, ma il confronto evita sorprese. - Usa le eccezioni tipizzate per gli errori applicativi: vedi Gestione eccezioni custom.