> For the complete documentation index, see [llms.txt](https://docs.eximee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eximee.com/budowanie-aplikacji/logika-biznesowa/scriptcode/jak-debugowac-skrypt-krok-po-kroku.md).

# Jak debugować skrypt

Gdy skrypt nie działa zgodnie z oczekiwaniami, szybka diagnoza pozwala wyeliminować problem na poziomie konfiguracji, danych wejściowych lub samego kodu logicznego.

## Weryfikacja wstępna na formularzu

Zanim przejdziesz do analizy kodu i logów w Kibanie, upewnij się, że warunki wywołania skryptu na interfejsie użytkownika są prawidłowo skonfigurowane.

1. **Sprawdź warunek wywołania skryptu**
   * Upewnij się, że warunek uruchomienia jest spełniony oraz że komponent, na którym zdefiniowany jest skrypt, prawidłowo nasłuchuje zdarzeń z komponentu wyzwalającego zmianę.
2. **Zweryfikuj parametry wejściowe**
   * Sprawdź, czy parametry wejściowe zostały odpowiednio zmapowane z formularza oraz czy komponent odbierający dane posiada aktywne nasłuchiwanie.
3. **Zweryfikuj parametry wyjściowe**
   * Upewnij się, że dane zwracane przez skrypt zostały prawidłowo przypisane do odpowiednich komponentów lub ich atrybutów.

## Analiza kodu źródłowego w ScriptCode

Gdy weryfikacja na formularzu nie wykaże błędów, a skrypt nadal zwraca niespodziewane wyniki lub zgłasza błąd wykonania, kolejnym krokiem jest dokładny przegląd logiki w kodzie źródłowym.

### Na co zwrócić uwagę podczas przeglądania kodu?

1. **Typy danych i formatowanie**
   * Upewnij się, że operujesz na odpowiednich typach danych (np. konwersja ciągów znaków na liczby przed wykonaniem obliczeń, prawidłowe parsowanie danych zgodnie z ich formatem, w szczególności z uwzględnieniem separatorów tysięcy i części dziesiętnej w wartościach liczbowych).
   * Do weryfikacji typów złożonych możesz skorzystać z operatora `instanceof`.
2. **Obsługa brakujących danych (`null` / `undefined`)**
   * Sprawdź, czy kod jest zabezpieczony na wypadek podania pustych parametrów wejściowych.
3. **Warunki brzegowe i logika biznesowa**
   * Zweryfikuj instrukcje warunkowe (`if/else`) oraz pętle.
   * Sprawdź, czy zwracany obiekt lub struktura danych odpowiada dokładnie temu, czego oczekuje komponent na formularzu.
4. **Wstawianie tymczasowych logów diagnostycznych**
   * Jeśli skrypt jest rozbudowany, warto w kluczowych miejscach dodać dodatkowe wpisy logujące zgodnie z [Logowanie w ScriptCode](/budowanie-aplikacji/logika-biznesowa/scriptcode/logowanie-w-scriptcode.md).

## Analiza logów w Kibanie

Gdy skrypt zgłasza błąd wykonania, zwraca niespodziewany wynik lub w ogóle się nie uruchamia, skorzystaj z Kibany. Narzędzie to umożliwia analizę logów aplikacyjnych i technicznych związanych z działaniem formularza w czasie rzeczywistym oraz dostarcza precyzyjnych informacji, które są niewidoczne z poziomu samego formularza.

### Konfiguracja widoku i filtrowanie logów

Aby sprawnie odnaleźć właściwe zdarzenia, skonfiguruj podstawowe opcje wyszukiwania i filtry.

<figure><img src="/files/lUSVxEmCA24fJlwb2F48" alt=""><figcaption><p><em><strong>Ilustracja 1.</strong> Widok główny modułu Discover w aplikacji Kibana</em></p></figcaption></figure>

### Opcje wyszukiwania

* **Data view (Widok danych):**
  * **Logi aplikacyjne** (np. `eximee-<środowisko>-<nazwaBanku>`) – podstawowy widok zawierający standardowe zdarzenia systemowe i komunikaty skryptów.
  * **Logi danych wrażliwych** (np. `kafka_eximee_sensitive`) – dedykowany indeks przeznaczony do śledzenia zdarzeń zawierających dane sensytywne.
* **Filtry środowiskowe:**
  * `log.environment` – pozwala zawęzić logi do konkretnego środowiska (np. `DEV`, `TEST`, `STAGE`, `PROD`).
  * `kubernetes.type` – umożliwia wybór typu kontenera lub usługi (np. podział na ruch sensytywny i niesensytywny).
* **Zakres czasu (Date Select):**
  * **Relative (Względny)** - Czas liczony wstecz od momentu analizy (np. *Last 30 minutes* – idealne podczas testowania na żywo).
  * **Absolute (Bezwzględny)** - Sztywno określony przedział czasowy od–do (np. od *04.12.2025 12:00* do *05.12.2025 07:30*).
  * **Wykres (Histogram)** - Przedział czasowy możesz również zaznaczyć bezpośrednio na wykresie liczby logów, rozciągając zaznaczenie myszką nad listą wyników.

### Opcje czytania logów

Po lewej stronie znajduje się panel z listą dostępnych filtrów. Wybierając ikonę (+) przy nazwie konkretnego filtra, dodasz go do widoku głównego w postaci czytelnej tabeli.

<figure><img src="/files/0g6x0vjd50DLGAzdmEVU" alt=""><figcaption><p><em><strong>Ilustracja 2.</strong> Panel filtrowania zdarzeń i wyboru pól w Kibanie</em></p></figcaption></figure>

Proponowane opcje przydatne do czytania logów:

<table data-header-hidden><thead><tr><th width="186.873291015625"></th><th></th></tr></thead><tbody><tr><td>Nazwa pola</td><td>Co pokazuje w logu?</td></tr><tr><td><code>timestamp</code></td><td>Czas rejestracji wpisu w logach z dokładnością do milisekund.</td></tr><tr><td><code>log.eximee.sessionToken</code></td><td>Unikalny token sesji wniosku/użytkownika w systemie Eximee. Pozwala odizolować cały ruch generowany przez jeden wniosek.</td></tr><tr><td><code>log.level</code></td><td>Poziom logu (<code>INFO</code>, <code>DEBUG</code>, <code>WARN</code>, <code>ERROR</code>, <code>TRACE</code>). Pozwala na szybkie odfiltrowanie błędów.</td></tr><tr><td><code>log.message</code></td><td>Właściwa treść komunikatu lub wyjścia ze skryptu. Pozwala na podgląd dokładnego stanu wykonania kodu oraz przetwarzanych danych.</td></tr><tr><td><code>log.stack_trace</code></td><td>Pełny ślad błędu (wyjątku systemowego). Wskazuje dokładną linię kodu oraz klasę, w której wystąpiła awaria.</td></tr><tr><td><code>log.data</code></td><td>Szczegółowy kontekst wykonania skryptu. Zawiera przekazane parametry wejściowe (inputs), zwracane wartości wyjściowe (outputs), zmienne kontekstowe oraz komunikaty diagnostyczne generowane bezpośrednio podczas pracy silnika skryptowego.</td></tr></tbody></table>

{% hint style="info" %}
Dostępność poszczególnych pól i miejsce zapisania danych może różnić się w zależności od rodzaju logu i konfiguracji wdrożenia.
{% endhint %}

### Poruszanie się po Kibanie

Najszybsze metody na zlokalizowanie szukanych zdarzeń to filtrowanie po:

* Danych kontekstowych wniosku: numer wniosku, identyfikator klienta (CIF, NIK).
* Nazwie skryptu / serwisu: nazwa konkretnego walidatora lub usługi.
* Przedziale czasowym: dokładne okno czasowe akcji użytkownika.
* Podzie na kontenery: wskazanie konkretnego kontenera aplikacyjnego.

{% hint style="info" %}
Identyfikatory klientów (takie jak CIF czy NIK) stanowią dane sensytywne. W zależności od polityki bezpieczeństwa oraz konfiguracji maskowania logów na danym środowisku, filtrowanie bezpośrednio po CIF może być niedostępne lub ograniczone. W takich przypadkach zaleca się wyszukiwanie po identyfikatorze procesowym (np. numerze wniosku).
{% endhint %}

### Przydatne zapytania KQL

Możesz także skorzystać z KQL (Kibana Query Language) w celu przeszukiwania logów i łączenia warunków operatorami `AND` lub `OR`.

<figure><img src="/files/ACc9eWlfBI2pgaueybV3" alt=""><figcaption><p><em><strong>Ilustracja 3.</strong> Pasek wyszukiwania z zapytaniem w języku KQL (Kibana Query Language)</em></p></figcaption></figure>

<table data-header-hidden><thead><tr><th width="186.873291015625"></th><th></th></tr></thead><tbody><tr><td>Cel wyszukiwania</td><td>Zapytanie KQL</td></tr><tr><td>Błędy konkretnego skryptu</td><td><code>log.data: "nazwaSkryptu" AND log.level: "ERROR"</code></td></tr><tr><td>Logi dla konkretnego wniosku</td><td><code>log.message: "IdWniosku"</code></td></tr><tr><td>Wykluczenie logów informacyjnych</td><td><code>NOT log.level: "INFO"</code></td></tr><tr><td>Łączenie wielu poziomów logów</td><td><code>log.level: ("ERROR" OR "WARN")</code></td></tr></tbody></table>

{% hint style="info" %}
Dostępność poszczególnych pól i miejsce zapisania danych może różnić się w zależności od rodzaju logu i konfiguracji wdrożenia.
{% endhint %}

## Przykłady analizy logów w Kibanie

**Wywołanie skryptu (ScriptCode)**

Logi wyszukujemy w Kibanie po nazwie skryptu (korzystając z filtru `log.data`). Pozwala to prześledzić cały cykl wykonania: sprawdzić dane wejściowe, wynik wyjściowy, poprawność działania logiki biznesowej oraz wyliczone wartości.

* Wejście do skryptu (parametry przekazane z formularza):

  ```
  - >> JavaScriptServiceHandler called [service=jmWniosekKredytowyAreaPercentageCalculator, parameters={businessArea=[11,00], LOCALE=[pl], monthsCount=[12], totalArea=[111,00]}]
  ```
* Wyjście ze skryptu (zwrócony wynik):

  ```
  - << JavaScriptServiceHandler finished execution [service=jmWniosekKredytowyAreaPercentageCalculator, result=[{result=9,9}]]
  ```

<figure><img src="/files/07KcrfzUK6rBkyACOq71" alt=""><figcaption><p><em><strong>Ilustracja 4.</strong> Rejestracja wywołania skryptu wraz z parametrami wejściowymi i wynikiem</em></p></figcaption></figure>

**Wywołanie walidatora**

Podobnie jak w przypadku skryptów, logi walidatorów filtrujemy po ich nazwie. Pozwala to podejrzeć przekazane dane wejściowe, kontekst wywołania oraz ewentualne komunikaty błędów.

* Początek walidacji:

  ```
  - >> ValidationScriptHandler called validator [name=jmWniosekKredytowyMinValueValidator, parameters={VALIDATION_CONTEXT=[PAGE_CHANGE_FORWARD], minValue=[2], LOCALE=[pl], userInput=[1]}]
  ```
* Zakończenie walidacji (zwrócona walidacja negatywna):

  ```
  - << ValidationScriptHandler finished executing validator [name=jmWniosekKredytowyMinValueValidator, result=[ValidationMessage [key: pl.error.minLimit, parameters: [2, Minimalna wartość dla tego pola wynosi {}.], attributes: {}, actions: null]]]
  ```

<figure><img src="/files/0SgTOarvXxbNpsuOd4bU" alt=""><figcaption><p><em><strong>Ilustracja 5.</strong> Przebieg wywołania walidatora zakończony komunikatem błędu (walidacja negatywna)</em></p></figcaption></figure>

**Błędy wykonania skryptu**

W przypadku wystąpienia nieobsłużonego wyjątku podczas wykonywania skryptu, w Kibanie rejestrowany jest błąd wykonania wraz ze ścieżką stosu (stack trace). Analizując wywołania kolejnych klas w stosie, możemy precyzyjnie zidentyfikować bezpośrednią przyczynę awarii — na przykład błąd matematyczny związany z dzieleniem przez zero:

```
Caused by: java.lang.ArithmeticException: / by zero
```

<figure><img src="/files/pmeGN8xaRCnHdwNnmkOy" alt=""><figcaption><p><em><strong>Ilustracja 6.</strong> Logi prezentujące nieobsłużony wyjątek (stack trace)</em></p></figcaption></figure>

**Wykorzystanie poziomów logowania**

Do tymczasowego śledzenia stanu aplikacji oraz weryfikacji wartości zmiennych w skryptach ScriptCode służy metoda `Logger.info(...)`. Umożliwia ona zapisywanie komunikatów diagnostycznych w logach systemowych.

```
// Przykład tymczasowego logu diagnostycznego w ScriptCode:
Logger.info("Wartość parametru wynosi: " + paramValue);
```

<figure><img src="/files/02ZnVBPtvXbGK1xaSPaS" alt=""><figcaption><p><em><strong>Ilustracja 7.</strong> Rejestracja wpisu diagnostycznego ze skryptu w Kibanie</em></p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.eximee.com/budowanie-aplikacji/logika-biznesowa/scriptcode/jak-debugowac-skrypt-krok-po-kroku.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
