Jeśli uruchamiam długi skrypt R z wiersza poleceń (R --slave script.R), jak mogę sprawić, aby podawał numery wierszy w przypadku błędów?
Nie chcę dodawać poleceń debugowania do skryptu, jeśli to w ogóle możliwe - chcę tylko, aby R zachowywał się jak większość innych języków skryptowych ...
Odpowiedzi:
Nie da ci to numeru linii, ale powie ci, gdzie wystąpiła awaria na stosie wywołań, co jest bardzo pomocne:
[Edit:] Podczas uruchamiania skryptu z wiersza poleceń będziesz musiał pominąć jedno lub dwa wywołania, zobacz traceback () dla interaktywnych i nieinteraktywnych sesji języka R
Nie znam innego sposobu na zrobienie tego bez zwykłych podejrzanych o debugowanie:
Możesz spojrzeć na ten powiązany post.
[Edycja:] Przepraszamy ... właśnie zobaczyłem, że uruchamiasz to z linii poleceń. W takim przypadku sugerowałbym pracę z opcjami (błędami). Oto prosty przykład:
Możesz utworzyć tak rozbudowany skrypt, jak chcesz, pod warunkiem błędu, więc powinieneś po prostu zdecydować, jakie informacje potrzebujesz do debugowania.
W przeciwnym razie, jeśli istnieją określone obszary, którymi się martwisz (np. Łączenie się z bazą danych), zawiń je w funkcję tryCatch ().
źródło
options(error=function() { traceback(2); if(!interactive()) quit("no", status = 1, runLast = FALSE) })
(patrz komentarz zaakceptowanej odpowiedzi). Myślę, że sensowne byłoby dodanie go do odpowiedzi, a nie tylko podanie linku do innego wątku.Doing
options(error=traceback)
dostarcza trochę więcej informacji o zawartości wierszy prowadzących do błędu. Powoduje wyświetlenie śledzenia wstecznego, jeśli wystąpi błąd, a dla niektórych błędów ma numer linii poprzedzony prefiksem#
. Ale jest trafiony lub chybiony, wiele błędów nie otrzyma numerów linii.źródło
No traceback available
po błędzie.Wsparcie dla tego pojawi się w wersji 2.10 i późniejszych. Duncan Murdoch właśnie wysłał wiadomość do r-devel 10 września 2009 na temat findLineNum i setBreapoint :
źródło
Robisz to przez ustawienie
Zastanawiam się tylko, dlaczego to ustawienie nie jest domyślne w R? Powinno być, tak jak w każdym innym języku.
źródło
Określenie globalnej opcji R do obsługi błędów innych niż katastrofa działało w moim przypadku, wraz ze dostosowanym przepływem pracy do przechowywania informacji o błędzie i sprawdzania tych informacji po awarii. Obecnie używam wersji R 3.4.1. Poniżej zamieściłem opis przepływu pracy, który działał dla mnie, a także kod, którego użyłem do ustawienia opcji globalnej obsługi błędów w R.
Jak skonfigurowałem, obsługa błędów tworzy również plik RData zawierający wszystkie obiekty w pamięci roboczej w momencie wystąpienia błędu. Ten zrzut można wczytać z powrotem do
load()
języka R za pomocą, a następnie można interaktywnie sprawdzić różne środowiska, jakie istniały w momencie wystąpienia błędudebugger(errorDump)
.Zwrócę uwagę, że udało mi się uzyskać numery wierszy w danych
traceback()
wyjściowych z dowolnych funkcji niestandardowych w stosie, ale tylko wtedy, gdy użyłem tejkeep.source=TRUE
opcji podczas wywoływaniasource()
jakichkolwiek funkcji niestandardowych używanych w moim skrypcie. Bez tej opcji ustawienie opcji globalnej obsługi błędów, jak poniżej, wysłało pełne dane wyjściowetraceback()
do dziennika błędów o nazwieerror.log
, ale numery wierszy nie były dostępne.Oto ogólne kroki, które wykonałem w moim przepływie pracy i jak mogłem uzyskać dostęp do zrzutu pamięci i dziennika błędów po nieinteraktywnej awarii języka R.
Na górze głównego skryptu, który wywoływałem z wiersza poleceń, umieściłem następujący tekst. To ustawia globalną opcję obsługi błędów dla sesji języka R. Mój główny skrypt został nazwany
myMainScript.R
. Różne wiersze w kodzie mają po nich komentarze opisujące, co robią. Zasadniczo, z tą opcją, gdy R napotka błąd, który wyzwalastop()
, utworzy plik zrzutu RData (* .rda) pamięci roboczej we wszystkich aktywnych środowiskach w katalogu,~/myUsername/directoryForDump
a także zapisze dziennik błędów nazwanyerror.log
z kilkoma przydatnymi informacjami do ten sam katalog. Możesz zmodyfikować ten fragment kodu, aby dodać inną obsługę w przypadku błędu (np. Dodać sygnaturę czasową do pliku zrzutu i nazwy plików dziennika błędów itp.).Upewnij się, że z głównego skryptu i wszelkich kolejnych wywołań funkcji, za każdym razem, gdy funkcja jest pobierana,
keep.source=TRUE
używana jest opcja . To znaczy, aby utworzyć źródło funkcji, użyłbyśsource('~/path/to/myFunction.R', keep.source=TRUE)
. Jest to wymagane, aby danetraceback()
wyjściowe zawierały numery wierszy. Wygląda na to, że możesz również ustawić tę opcję globalnieoptions( keep.source=TRUE )
, ale nie testowałem tego, aby sprawdzić, czy to działa. Jeśli nie potrzebujesz numerów linii, możesz pominąć tę opcję.Rscript myMainScript.R
. Spowoduje to uruchomienie nowej nieinteraktywnej sesji języka R i uruchomienie skryptumyMainScript.R
. Fragment kodu podany w kroku 1, który został umieszczony na górze,myMainScript.R
ustawia opcję obsługi błędów dla nieinteraktywnej sesji języka R.myMainScript.R
. Może to być w samym skrypcie głównym lub głęboko zagnieżdżone kilka funkcji. Po napotkaniu błędu obsługa zostanie wykonana zgodnie z opisem w kroku 1, a sesja języka R zostanie zakończona.errorDump.rda
i dzienniku błędów o nazwieerror.log
są tworzone w katalogu określonym'~/myUsername/directoryForDump'
w ustawieniu opcji globalnej obsługi błędów.W wolnym czasie przejrzyj
error.log
informacje o błędzie, w tym sam komunikat o błędzie i pełny ślad stosu prowadzący do błędu. Oto przykład dziennika, który jest generowany w przypadku błędu; zwróć uwagę, że liczby po#
znaku to numery wierszy błędu w różnych punktach stosu wywołań:W wolnym czasie możesz załadować
errorDump.rda
do interaktywnej sesji języka R za pomocąload('~/path/to/errorDump.rda')
. Po załadowaniu wywołaj,debugger(errorDump)
aby przejrzeć wszystkie obiekty języka R w pamięci w dowolnym z aktywnych środowisk. Zobacz pomoc języka R, abydebugger()
uzyskać więcej informacji.Ten przepływ pracy jest niezwykle pomocny podczas uruchamiania języka R w pewnym typie środowiska produkcyjnego, w którym nieinteraktywne sesje języka R są inicjowane w wierszu poleceń i chcesz zachować informacje o nieoczekiwanych błędach. Możliwość zrzutu pamięci do pliku, którego można użyć do sprawdzenia pamięci roboczej w momencie wystąpienia błędu, wraz z numerami wierszy błędu w stosie wywołań, ułatwiają szybkie debugowanie pośmiertne tego, co spowodowało błąd.
źródło
Najpierw,
options(show.error.locations = TRUE)
a potemtraceback()
. Numer linii błędu zostanie wyświetlony po #źródło