Error in strsplit: l'argument n'est pas une chaîne de caractères


`> Blockquote`

library(shiny)
library(shinyWidgets)
library(leaflet)
library(tidyverse)
library(lubridate)
library(shinybusy)
library(readr)
library(data.table)
library(utils)
library(readxl)
library(R.utils)
library(base)
##--------------------------------------------------------------------------------------------
##  Importation du script contenu dans le fichier "extract_meteo.R"contenant 2 fonctions :  --
##--------------------------------------------------------------------------------------------
#     1- maj_stations : crée le fichier "df_stations.rds" à partir des stations disponibles et le fichier "df_convISO_dispo.rds" -> conversion pays en français et code ISO3166 alpha 2
#     2- extraction : retourne une liste à 4 dimension contenant les noms des fichiers excels à créer et les données météos pour les deux fichiers Opro et toutes les données en se connectant au serveurs meteostat
source("extract_meteo.R")

#Mise à jour des stations, pas important de le faire à chaque ouverture car peu de chances de changement
#maj_stations()

df_stations <- read_rds("df_stations.rds") #chargement tableau avec toutes les stations 
df_conversion_ISO_dispo <- read_rds("df_convISO_dispo.rds") #chargement d'un fichier utilisé pour faire la conversion entre le code iso 3166 alpha 2 et le nom du pays en francais


ui <- bootstrapPage(
  ##---------------------------------------------------------------
  ##                          Interface                          --
  ##---------------------------------------------------------------
  add_busy_spinner(spin = "radar", margins = c(10, 20)), # Logo de chargement
  tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
  leafletOutput("map", width = "100%", height = "100%"), # Carte 
  absolutePanel(id='nomappli',top = 0, left=70,img(src = 'EDFMeteostat.png',height = 68.35, width = 397.5),
                downloadButton("dl_aide", "Aide"),
                downloadButton("dl_rapport", "Rapport Ms-Pro")),# Logo 
  absolutePanel(id='parametres',class='panel panel-default' ,top = 10, right = 10, # Panneau au premier plan par dessus la carte
                width = "auto", fixed = TRUE, draggable = TRUE,
                p(),
                p(strong("Extraction de données météos au pas horaire")),
                pickerInput("pays", label = "Pays", # Menu déroulant sélection pays
                            choices = df_conversion_ISO_dispo[[3]],
                            selected = "France Metropole - FR Metro", #sélection par défaut france métropole
                            #multiple = TRUE,
                            options = list(`live-search` = TRUE)),
                checkboxInput("chexkbox_recent", label = "Avec anciennes stations (arretées depuis plus d'un an)", value = FALSE), #choix données récentes
                pickerInput("annee", label = "Choix d'année d'extraction", 
                            choices = c(year(Sys.Date()),
                                        year(Sys.Date() %m-% years(1)),
                                        year(Sys.Date() %m-% years(2)),
                                        year(Sys.Date() %m-% years(3)),
                                        year(Sys.Date() %m-% years(4)),
                                        year(Sys.Date() %m-% years(5)),
                                        year(Sys.Date() %m-% years(6)),
                                        year(Sys.Date() %m-% years(7)),
                                        year(Sys.Date() %m-% years(8)),
                                        year(Sys.Date() %m-% years(9)),
                                        year(Sys.Date() %m-% years(10)),
                                        year(Sys.Date() %m-% years(11)),
                                        year(Sys.Date() %m-% years(12)),
                                        year(Sys.Date() %m-% years(13)),
                                        year(Sys.Date() %m-% years(14)),
                                        year(Sys.Date() %m-% years(15)),
                                        year(Sys.Date() %m-% years(16)),
                                        year(Sys.Date() %m-% years(17)),
                                        year(Sys.Date() %m-% years(18)),
                                        year(Sys.Date() %m-% years(19)),
                                        year(Sys.Date() %m-% years(20)),
                                        year(Sys.Date() %m-% years(21)),
                                        year(Sys.Date() %m-% years(22))
                            ),
                            selected = year(Sys.Date() %m-% years(1))
                ),
                p(),
                p(strong('Calcul des DJU :')),
                sliderInput("slider_chauf", label = "Température de consigne chauffage (°C)", min = 15, max = 25, value = 18),
                sliderInput("slider_clim", label = "Température de consigne climatisation (°C)", min = 15, max = 25, value = 18),
                actionButton("export", label = "Exporter"),
                p(),
                
  )
)
#=========================================================================================================== 
server <- function(input, output, session) { # -------------SERVER------------------------------------------
  #=========================================================================================================== 
  #maj_stations()
  valeurs <- reactiveValues() #liste pour mettre en mémoire des variables "globales"
  
  ##------------------------------------------------------------------------
  ##  Filtration des stations à afficher en fonction du pays sélectionné  --
  ##------------------------------------------------------------------------
  filteredData <- reactive({
    df_filtr_stations <- df_stations
    if (input$chexkbox_recent == FALSE){ # case à cocher si données < à 1 an
      df_filtr_stations  <- filter(df_filtr_stations , inventory.hourly.end >Sys.Date() %m-% years(1))
    }
    if (input$pays == 'France Metropole - FR Metro'){ # Centrage sur la france
      filter(df_filtr_stations , country == 'FR', timezone == 'Europe/Paris')
    } else {
      l=which(df_conversion_ISO_dispo[[3]]==input$pays) # Prend la ligne qui correspond au pays choisi
      filter(df_filtr_stations, country == df_conversion_ISO_dispo[l,2]) #Filtration en fonction du code ISO du pays
    }
  })
  ##---------------------------------------------------------------
  ##                        Click station                        --
  ##---------------------------------------------------------------
  observe({ #Stockage de l'identifiant d'une station dans la liste "valeurs" quand l'utilisateur clique sur un marker
    click<-input$map_marker_click
    if(is.null(click))
      return()
    valeurs$id <- click$id
  })
  ##---------------------------------------------------------------
  ##                            CARTE                            --
  ##---------------------------------------------------------------
  #Affichage de la carte
  output$map <- renderLeaflet({
    leaflet(filteredData()) %>%
      addTiles(urlTemplate = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png') %>%
      #addTiles(urlTemplate = "http://10.52.212.139:80/styles/basic-preview/{z}/{x}/{y}.png") %>%
      #addTiles(urlTemplate = "https://tilserver.apps.okd413.retd.edf.fr/styles/basic-preview/{z}/{x}/{y}.png") %>% 
      #addTiles() %>% 
      addProviderTiles(providers$OpenStreetMap.France, options = providerTileOptions(noWrap = TRUE)) %>% # Carte en Français
      addMarkers(~location.longitude, ~location.latitude, #colonnes dans le dataframe
                 #label = ~name.en,
                 popup = ~popuptext, #code HTML dans la dernière colonne du DF
                 layerId = ~id
      )})
  #Mise a jour affichage de la carte
  observe({
    leafletProxy("map", data = filteredData()) %>%
      clearShapes() %>%
      addMarkers(~location.longitude, ~location.latitude, #colonnes dans le df
                 #label = ~name.en, 
                 popup = ~popuptext,
                 layerId = ~id
      )
  })
  ##----------------------------------------------------------------
  ##                  Chargement du fichier meteo                 --
  ##----------------------------------------------------------------  
  data_meteo <- reactive({
    inFile <- input$file
    if (is.null(inFile)){
      return(NULL)
    }
    df_meteo <- fread(inFile$datapath)
    return(df_meteo)
    #saveRDS(df_meteo,'df_meteo_test_tl_fichier.rds')
    #return(df_meteo)
  })
  
  
  ##----------------------------------------------------------------
  ##                  Click du bouton "exporter"                  --
  ##----------------------------------------------------------------
  observeEvent(input$export, {
    if (is.null(valeurs$id)){ #message d'erreur si exporter sans avoir sélectionné de station
      showModal(modalDialog(
        "Pas de station sélectionnée, cliquez sur une station pour la sélectionner.",
        footer = modalButton("Retour"),
      ))
      return()
    }
    showModal(modalDialog(
      title = NULL,
      p(strong("1 - Cliquer sur ce lien :",
               a(nom_lien(valeurs$id,input$annee), 
                 href= paste("https://bulk.meteostat.net/v2/hourly/",input$annee,"/",valeurs$id,".csv.gz", sep=""), target="_blank"),
               " ")),
      p(strong("2 - Enregistrer le fichier"),("si possible le renomer, mais ne pas changer l'extention du fichier '.csv.gz') ")),
      p("Exemple nom : melun-2021-07153.csv.gz "),
      p(strong("3 - Cliquer sur 'Parcourir' et sélectionner le fichier tout juste téléchargé")),
      fileInput("file", label = NULL, buttonLabel = 'Parcourir', accept = ".csv.gz"),
      p(strong('4 - Cliquer sur "Lancer le traitement"')),
      actionButton('actionbutton_analyse','Lancer le traitement'),
      footer = modalButton("Retour"),
      p(),
      p("Conseil : Supprimer le fichier téléchargé après l'exportation")
    ))
  })
  ##----------------------------------------------------------------
  ##                  Click du bouton "Confirmer"                 --
  ##----------------------------------------------------------------
  observeEvent(input$actionbutton_analyse, {
    if (is.null(data_meteo())){
      showModal(modalDialog(
        "Erreur, pas de fichier importé, veuillez sélectionner le fichier téléchargé à partir du lien généré.",
        footer = modalButton("Retour"),
      ))
      return()
    }
    showModal(modalDialog(
      footer = NULL,
      p("Traitement des données en cours veuillez patienter ...", align = "center"),
      div("Temps estimé inférieur à 2 min", align = "center"),
      add_busy_spinner(spin = "self-building-square") # Logo de chargement
    ))
    ##----------------------------------------------------------------
    ##                    Traitement des données                    --
    ##----------------------------------------------------------------
    withProgress(message = 'Traitement en cours', value = 0, { # barre de chargement
      incProgress(1/17520, detail = "Récupération des données ...")
      fichier_meteo <- data_meteo()
      id_station <- valeurs$id
      annee <- input$annee
      #--------------------------------------------------------------------------
      df_stations <- read_rds("df_stations.rds")
      date_debut <- as.Date(paste(annee, '-01-01', sep = ''))
      date_fin <- as.Date(paste(annee, '-12-31', sep = ''))
      
      df_meteo <- fichier_meteo
      colnames(df_meteo) <- c('Date_', 'Heure', 'Temp','dwp','HR','prcp','neige','dirvt','vitvt','maxvt','patm','tsoleil','coco')
      ligne_station = which(df_stations[[1]]==id_station) # positionnement de la station dans le fichier id_station
      df_meteo <- filter(df_meteo,Date_ >= date_debut, Date_<= date_fin) #filtration entre date début et fin
      #mise de l'heure dans la date
      dt_dates <- data.frame(as.POSIXct(paste(type.convert(df_meteo[[1]], as.is = TRUE),type.convert(df_meteo[[2]], as.is = TRUE), ":00", sep=""), format="%Y-%m-%d %H:%M", tz="UTC"))
      #Changement de la date en date locale
      dt_dates[[2]] <- lubridate::with_tz(dt_dates[[1]], tzone = df_stations[ligne_station,4])
      
      df_meteo$Date_ <- dt_dates[[1]]
      df_meteo$Heure <- dt_dates[[2]]
      
      colnames(df_meteo)<-c('Date_UTC', 'Date_Locale', 'Temp(deg C)','pt_rosee(deg C)','HR(%)','precipitations(mm)','neige(mm)','dirvt(degre)','vitvt(km/h)','maxvt(km/m)','Patm alt=0 (hPa)','tsoleil(min)','code_condition_meteo')
      #--------------------------------------------------------------------------- verfi ficher
      timezone <- df_stations[ligne_station,4]
      l = 1 # compteur de ligne total
      k = 1 # compteur de ligne df_meteo
      j=0 #compteur de tous les duplicats
      t=0
      h=0
      ligne = 0
      if (as.numeric(annee)%%4 == 0){ #annee bissextile
        nb_heures_annee <- 8784
      } else {
        nb_heures_annee <- 8760
      }
      
      # 1 - Repérage de lignes manquantes
      date_i <- as.POSIXct(paste(annee, '-01-01 00:00', sep = ''), tz = 'UTC')
      if (nrow(df_meteo) != nb_heures_annee | any(is.na(df_meteo$`Temp(deg C)`)) | any(is.na(df_meteo$`HR(%)`))){ #Detection si besoin d'analyser
        while (year(date_i) == annee ){
          if (l==1){ #initialisation
            df_meteo_annee <- data.frame(df_meteo[1,]) #copie première ligne pour avoir les formats
            df_meteo_annee[1,14] <- NA # valeur 1 si ligne dupliquée
            df_meteo_annee[1,15] <- NA # valeur 1 si température dupliquée
            df_meteo_annee[1,16] <- NA # valeur 1 si humidité dupliquée
            colnames(df_meteo_annee) <- c('Date_UTC', 'Date_Locale', 'Temp(deg C)','pt_rosee(deg C)','HR(%)','precipitations(mm)','neige(mm)','dirvt(degre)','vitvt(km/h)','maxvt(km/m)','Patm alt=0 (hPa)','tsoleil(min)','code_condition_meteo','duplicat_ligne','duplicat_temp','duplicat_HR')
            k = k + 1
            if (!(df_meteo$Date_UTC[1] == date_i)){# première heure de l'année n'existe pas
              df_meteo_annee[1,] <- list(date_i,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA)
              k = 1 
            }
          } else { # à chaque autre ligne
            if (df_meteo$Date_UTC[k] == date_i){ #La date existe dans df_meteo
              df_meteo_annee[l,1:13] <- df_meteo[k,]
              k = k+1 #ligne suivante de df_meteo
            } else { #la date n'existe pas
              df_meteo_annee[l,1:13] <- df_meteo[k-1,] # duplication ligne d'avant
              df_meteo_annee[l,1] <- date_i # changement de la date
              df_meteo_annee[l,14] <- 1 # marquage ligne dupliquée
            }
          }
          # Incrémentation
          l = l + 1 #prochaine ligne
          date_i = date_i + hours(1) # prochaine heure
          incProgress(1/17520, detail = paste("Recherche valeurs manquantes, ligne:", l))
          if (date_i > date(Sys.time())){
            break
          }
        } # fin while
        df_meteo <- df_meteo_annee
        df_meteo$Date_Locale <- lubridate::with_tz(df_meteo$Date_UTC, tzone = timezone)
        # 2 - Duplication des températures et humidités manquantes
        
        for (i in 1:nrow(df_meteo)){
          if (is.na(df_meteo[i,3])){ #trouve valeur NA en température
            df_meteo[i,15]<-1
            if (i > 1){
              df_meteo[i,3] <- df_meteo[i-1,3]
            } else if (is.null(df_meteo[i+1,3])) {
              df_meteo[i+1,3] <- df_meteo[i+2,3]
            } else {
              df_meteo[i,3] <- df_meteo[i+1,3]
            }
          }
          if (is.na(df_meteo[i,5])){ # humidité
            df_meteo[i,16]<-1
            if (i > 1){
              df_meteo[i,5] <- df_meteo[i-1,5]
            } else if (is.null(df_meteo[i+1,5])) {
              df_meteo[i+1,5] <- df_meteo[i+2,5]
            } else {
              df_meteo[i,5] <- df_meteo[i+1,5]
            }
          }
          if (!(is.na(df_meteo[i,14])) | !(is.na(df_meteo[i,15])) | !(is.na(df_meteo[i,16])) ){ # Si il y a eu une duplication
            j = j + 1
            if (j == 1){ 
              df_changement <- data.frame(df_meteo[i,])
            } else if (j > 1) {
              df_changement[nrow(df_changement)+1,] <- df_meteo[i,]
            }
          }
          incProgress(1/17520, detail = paste("Duplication valeurs manquantes, ligne", i))
        } # fin for
      }
      
      if (j == 0){ # aucun changement effectué
        df_changement <- data.frame(x = 'Aucune valeur manquante')
      } else {
        t = sum(df_changement[[15]])
        h = sum(df_changement[[16]])
        ligne = sum(df_changement[[14]])
      }
      if (is.na(h)){
        h=0
      }
      if (is.na(t)){
        t=0
      }
      if (is.na(ligne)){
        ligne = 0
      }
      list_verif <- list(df_meteo,t,h,nrow(df_meteo),df_changement,ligne,j)
      ##----------------------------------------------------------------
      ##                         FICHIER OPRO                         --
      ##----------------------------------------------------------------
      df_opro <- data.frame(df_meteo$Date_Locale,df_meteo$Temp,df_meteo$HR,df_meteo$vitvt)
      ##--------------------------------------------------------------------
      ##  creation des noms fichiers en fonction des stations pays dates  --
      ##--------------------------------------------------------------------
      j=which(df_stations$id == id_station)
      # nom_fichier <- paste('Meteo_OPro_',df_stations$name.en[j],'_',df_stations$country[j],'_',type.convert(format(date_debut,'%d-%m-%y'),as.is = TRUE),'_',type.convert(format(date_fin,'%d-%m-%y'), as.is=TRUE),'.xlsx', sep='')
      # nom_fichier_tout <- paste('Meteo_tout_',df_stations$name.en[j],'_',df_stations$country[j],'_',type.convert(format(date_debut,'%d-%m-%y'),as.is = TRUE),'_',type.convert(format(date_fin,'%d-%m-%y'), as.is=TRUE),'.xlsx', sep='')
      nom_fichier <- paste('Meteo_OPro_',df_stations$name.en[j],'_',df_stations$country[j],'_',annee,'.csv', sep='')
      nom_fichier_tout <- paste('Meteo_tout_',df_stations$name.en[j],'_',df_stations$country[j],'_',annee,'.csv', sep='')
      nom_fichier_changements <- paste('Valeurs_meteos_dupliquees_',df_stations$name.en[j],'_',df_stations$country[j],'_',annee,'.csv', sep='')
      #Réectriture du fichier meteo avec les deux premières colonnes date UTC et date locale
      df_meteo$Date_Locale <- lubridate::with_tz(df_meteo$Date_UTC, tzone = df_stations[ligne_station,4])
      #df_meteo$Date_UTC <- force_tz(df_meteo$Date_UTC, tzone = Sys.timezone()) #Forcage du changement de fuseau horaire pour qu'il n'y ai pas d'autoconversion dans le fichier excel
      df_meteo$Date_Locale <- force_tz(df_meteo$Date_Locale, tzone = Sys.timezone())
      
      #return(list(nom_fichier,nom_fichier_tout,df_opro,df_meteo,list_verif,nom_fichier_changements))
      valeurs$output <- list(nom_fichier,nom_fichier_tout,df_opro,df_meteo,list_verif,nom_fichier_changements)
    }) # fin barre de progression
    
    #valeurs$output <- extraction (data_meteo(),valeurs$id,input$annee) #Appel fonction extraction du module "extract_meteo"
    #=================================================================
    #COMPOSITION DE Valeurs$output, liste à 4 dimension :
    # list(1: nom fichier opro, 2: nom fichier tout, 3: df opro, 4: df meteo, 5: liste des resultats d'analyse du fichier)
    #=================================================================
    dupliq <- valeurs$output[[5]]
    DJU <- calcul_DJU(valeurs$output[[4]],input$dates,input$slider_chauf,input$slider_clim)
    valeurs$DJU <- DJU
    showModal(modalDialog( #Boite de dialogue pour télécharger les fichiers
      title = strong("L'extraction des données est terminée"),
      downloadButton("dl_opro", "Télécharger le ficher .csv OpTHum Pro : Date & heure locale | T (°C) | HR (%)"),
      p('(à ouvrir et enregistrer au format .xlsx avant importation dans OPro)'),
      downloadButton('dl_tout', 'Télécharger toutes les données météo disponibles (.csv)'),
      p(paste('Total des valeurs manquantes dupliquées', dupliq[7], 'sur', dupliq[4], 'valeurs')),
      downloadButton('dl_change', 'Détail valeurs dupliquées'),
      p(),
      p(strong(paste("DJU pour l'année",input$annee,' :'))),
      p(paste('DJU chauffage consigne ', input$slider_chauf,'°C   : ', DJU[1])),
      p(paste('DJU climatisation consigne ', input$slider_clim,'°C    : ', DJU[2])),
      p(strong('Les données sont issues du site ', a('Meteostat,', href= 'https://meteostat.net/fr/'), ' voir les ', a('conditions ', href='https://dev.meteostat.net/terms.html#use-of-services'),
               'et ',a('le détail de toutes les données.', href='https://dev.meteostat.net/bulk/hourly.html#structure'))),
      p(strong('Voir la ', a('librairie python', href= 'https://dev.meteostat.net/python/'), 'pour plus de contrôle sur les données et leur extraction')),
      em('Les données de Météostat sont généralement fournies selon les termes de la ', a('licence publique internationale Creative Commons Attribution-NonCommercial 4.0 (CC BY-NC 4.0).', href= 'https://creativecommons.org/licenses/by-nc/4.0/legalcode'),'
    Vous pouvez exploiter le matériel à toutes fins, même commerciales. Cependant, vous n êtes pas autorisé à redistribuer les données de Météostat "telles quelles" à des fins commerciales en dehors des États-Unis.
             Ceci est dû à ', a('la politique de la résolution 40 de l OMM.', href= 'https://community.wmo.int/resolution-40'),' Selon cette résolution, les données doivent être distribuées "gratuitement et sans restriction" et "au maximum au coût de reproduction et de livraison, sans frais pour les données et les produits eux-mêmes".'),
      footer = modalButton("Terminer"),
    ))
  })
  
  
  
  ##---------------------------------------------------------------
  ##              Paramétrage de l'excel OpTHum Pro              --
  ##---------------------------------------------------------------
  output$dl_opro <- downloadHandler( 
    filename = function() {valeurs$output[1]},
    content = function(file) {
      write.table( col.names = FALSE, valeurs$output[[3]],file, row.names = FALSE, dec = ",", sep = ";")
    })
  ##----------------------------------------------------------------
  ##        Paramétrage de l'excel avec toutes les données        --
  ##----------------------------------------------------------------
  output$dl_tout <- downloadHandler( 
    filename = function() {valeurs$output[2]},
    content = function(file) {
      data <- cbind.data.frame(valeurs$output[[4]],valeurs$DJU)
      write.table( col.names = TRUE, data ,file, row.names = FALSE, dec = ",", sep = ";")
    })
  ##------------------------------------------------------------------------
  ##        Paramétrage de l'excel le récap des valeurs manquantes        --
  ##------------------------------------------------------------------------
  output$dl_change <- downloadHandler( 
    filename = function() {valeurs$output[6]},
    content = function(file) {
      data_change <- valeurs$output[[5]]
      write.table( col.names = TRUE, data_change[[5]] ,file, row.names = TRUE, dec = ",", sep = ";")
    })
  ##---------------------------------------------------------------
  ##                        Fichier Aide PDF                     --
  ##---------------------------------------------------------------
  output$dl_aide <- downloadHandler( 
    filename = "Guide_meteostat_pro.pdf",
    content = function (file) {
      file.copy("www/aide.pdf", file)
    })
  ##---------------------------------------------------------------
  ##                     Fichier Rapport PDF                     --
  ##---------------------------------------------------------------  
  output$dl_rapport <- downloadHandler( 
    filename = "CR_2022_07_Meteostat.pdf",
    content = function (file) {
      file.copy("www/CR_2022_07_Meteostat.pdf", file)
    })
}

shinyApp(ui, server)

Since the strsplit() function does not appear in the code you shared, I wonder whether it appears in the file extract_meteo.R — does it?

Also, so you're aware: When you share large amounts of code, you should put it in a code block, like this:

```
put code here, between a pair of triple backticks (meaning, ```)
```

Could you edit your original post, above, so that the code is in a code block?

1 Like

use shiny::devmode() to get a stacktrace and look at that.

1 Like

je reformule ma question en francais si quelqu'un peut m'aider : mon application gère les fichiers CSV.gz directement via les interactions de l'utilisateur qui doit télécharger des données météorologiques depuis une source externe ( méteostat) , puis les charger dans l'application pour traitement. lorsque je télécharge le fichier et je lance le traitement l'erreur strsplit: l'argument n'est pas une chaine de caractères apparait et le fichier obtenu est sous forme HTML et pas un fichier csv.

I don't use shiny much, so I hope @nirgrahamuk will correct me if I'm wrong, but you could first try to follow his advice by adding:

devmode()
# Display the full stack trace when errors occur during Shiny app execution
register_devmode_option(
  "shiny.fullstacktrace",
  "Turning on full stack trace. To disable, call `options(shiny.fullstacktrace = FALSE)`",
  devmode_default = TRUE
)

to the top of your shiny app, and then share the resulting full error output.

1 Like

c'est ce que j'ai en sortie quand j'ai lancer l'application

shiny devmode - Using full shiny javascript file. To use the minified version, call `options(shiny.minified = TRUE)
This message is displayed once every 8 hours.
Avis : Error in strsplit: l'argument n'est pas une chaîne de caractères
shiny devmode - Turning on full stack trace. To disable, call `options(shiny.fullstacktrace = FALSE)`
This message is displayed once every 8 hours.
  100: h
   99: .handleSimpleError
   98: strsplit
   97: vapply
   96: value[[3L]]
   95: tryCatchOne
   94: tryCatchList
   93: tryCatch
   92: basename
   91: mime::guess_type
   90: getContentType
   89: %||%
   88: httpResponse
   87: func
   86: withVisible
   85: f
   84: Reduce
   83: withCallingHandlers
   82: domain$wrapSync
   81: promises::with_promise_domain
   80: captureStackTraces
   79: doTryCatch
   78: tryCatchOne
   77: tryCatchList
   76: tryCatch
   75: do
   74: hybrid_chain
   73: withCallingHandlers
   72: domain$wrapSync
   71: promises::with_promise_domain
   70: domain$wrapSync
   69: promises::with_promise_domain
   68: contextFunc
   67: env$runWith
   66: force
   65: domain$wrapSync
   64: promises::with_promise_domain
   63: withReactiveDomain
   62: domain$wrapSync
   61: promises::with_promise_domain
   60: Context$new(getDefaultReactiveDomain(), "[download]")$run
   59: shinysession$handleRequest
   58: force
   57: domain$wrapSync
   56: promises::with_promise_domain
   55: withReactiveDomain
   54: handler
   53: handler
   52: handlers$invoke
   51: withCallingHandlers
   50: domain$wrapSync
   49: promises::with_promise_domain
   48: captureStackTraces
   47: withCallingHandlers
   46: withLogErrors
   45: withCallingHandlers
   44: force
   43: withVisible
   42: withCallingHandlers
   41: domain$wrapSync
   40: promises::with_promise_domain
   39: captureStackTraces
   38: doTryCatch
   37: tryCatchOne
   36: tryCatchList
   35: tryCatch
   34: do
   33: hybrid_chain
   32: force
   31: withVisible
   30: withCallingHandlers
   29: domain$wrapSync
   28: promises::with_promise_domain
   27: captureStackTraces
   26: doTryCatch
   25: tryCatchOne
   24: tryCatchList
   23: tryCatch
   22: do
   21: hybrid_chain
   20: handler
   19: func
   18: compute
   17: doTryCatch
   16: tryCatchOne
   15: tryCatchList
   14: tryCatch
   13: rookCall
   12: <Anonymous>
   11: execCallbacks
   10: run_now
    9: service
    8: serviceApp
    7: ..stacktracefloor..
    6: withCallingHandlers
    5: domain$wrapSync
    4: promises::with_promise_domain
    3: captureStackTraces
    2: ..stacktraceoff..
    1: shiny::runApp
Avis : Error in strsplit: l'argument n'est pas une chaîne de caractères
  100: h
   99: .handleSimpleError
   98: strsplit
   97: vapply
   96: value[[3L]]
   95: tryCatchOne
   94: tryCatchList
   93: tryCatch
   92: basename
   91: mime::guess_type
   90: getContentType
   89: %||%
   88: httpResponse
   87: func
   86: withVisible
   85: f
   84: Reduce
   83: withCallingHandlers
   82: domain$wrapSync
   81: promises::with_promise_domain
   80: captureStackTraces
   79: doTryCatch
   78: tryCatchOne
   77: tryCatchList
   76: tryCatch
   75: do
   74: hybrid_chain
   73: withCallingHandlers
   72: domain$wrapSync
   71: promises::with_promise_domain
   70: domain$wrapSync
   69: promises::with_promise_domain
   68: contextFunc
   67: env$runWith
   66: force
   65: domain$wrapSync
   64: promises::with_promise_domain
   63: withReactiveDomain
   62: domain$wrapSync
   61: promises::with_promise_domain
   60: Context$new(getDefaultReactiveDomain(), "[download]")$run
   59: shinysession$handleRequest
   58: force
   57: domain$wrapSync
   56: promises::with_promise_domain
   55: withReactiveDomain
   54: handler
   53: handler
   52: handlers$invoke
   51: withCallingHandlers
   50: domain$wrapSync
   49: promises::with_promise_domain
   48: captureStackTraces
   47: withCallingHandlers
   46: withLogErrors
   45: withCallingHandlers
   44: force
   43: withVisible
   42: withCallingHandlers
   41: domain$wrapSync
   40: promises::with_promise_domain
   39: captureStackTraces
   38: doTryCatch
   37: tryCatchOne
   36: tryCatchList
   35: tryCatch
   34: do
   33: hybrid_chain
   32: force
   31: withVisible
   30: withCallingHandlers
   29: domain$wrapSync
   28: promises::with_promise_domain
   27: captureStackTraces
   26: doTryCatch
   25: tryCatchOne
   24: tryCatchList
   23: tryCatch
   22: do
   21: hybrid_chain
   20: handler
   19: func
   18: compute
   17: doTryCatch
   16: tryCatchOne
   15: tryCatchList
   14: tryCatch
   13: rookCall
   12: <Anonymous>
   11: execCallbacks
   10: run_now
    9: service
    8: serviceApp
    7: ..stacktracefloor..
    6: withCallingHandlers
    5: domain$wrapSync
    4: promises::with_promise_domain
    3: captureStackTraces
    2: ..stacktraceoff..
    1: shiny::runApp

The issue is that I don't have the strsplit function in my code.

i tried shiny::devmode() and i have this:

Listening on http://127.0.0.1:6592
shiny devmode - Using full shiny javascript file. To use the minified version, call `options(shiny.minified = TRUE)`
This message is displayed once every 8 hours.
Avis : Error in strsplit: l'argument n'est pas une chaîne de caractères
shiny devmode - Turning on full stack trace. To disable, call `options(shiny.fullstacktrace = FALSE)`
This message is displayed once every 8 hours.
  100: h
   99: .handleSimpleError
   98: strsplit
   97: vapply
   96: value[[3L]]
   95: tryCatchOne
   94: tryCatchList
   93: tryCatch
   92: basename
   91: mime::guess_type
   90: getContentType
   89: %||%
   88: httpResponse
   87: func
   86: withVisible
   85: f
   84: Reduce
   83: withCallingHandlers
   82: domain$wrapSync
   81: promises::with_promise_domain
   80: captureStackTraces
   79: doTryCatch
   78: tryCatchOne
   77: tryCatchList
   76: tryCatch
   75: do
   74: hybrid_chain
   73: withCallingHandlers
   72: domain$wrapSync
   71: promises::with_promise_domain
   70: domain$wrapSync
   69: promises::with_promise_domain
   68: contextFunc
   67: env$runWith
   66: force
   65: domain$wrapSync
   64: promises::with_promise_domain
   63: withReactiveDomain
   62: domain$wrapSync
   61: promises::with_promise_domain
   60: Context$new(getDefaultReactiveDomain(), "[download]")$run
   59: shinysession$handleRequest
   58: force
   57: domain$wrapSync
   56: promises::with_promise_domain
   55: withReactiveDomain
   54: handler
   53: handler
   52: handlers$invoke
   51: withCallingHandlers
   50: domain$wrapSync
   49: promises::with_promise_domain
   48: captureStackTraces
   47: withCallingHandlers
   46: withLogErrors
   45: withCallingHandlers
   44: force
   43: withVisible
   42: withCallingHandlers
   41: domain$wrapSync
   40: promises::with_promise_domain
   39: captureStackTraces
   38: doTryCatch
   37: tryCatchOne
   36: tryCatchList
   35: tryCatch
   34: do
   33: hybrid_chain
   32: force
   31: withVisible
   30: withCallingHandlers
   29: domain$wrapSync
   28: promises::with_promise_domain
   27: captureStackTraces
   26: doTryCatch
   25: tryCatchOne
   24: tryCatchList
   23: tryCatch
   22: do
   21: hybrid_chain
   20: handler
   19: func
   18: compute
   17: doTryCatch
   16: tryCatchOne
   15: tryCatchList
   14: tryCatch
   13: rookCall
   12: <Anonymous>
   11: execCallbacks
   10: run_now
    9: service
    8: serviceApp
    7: ..stacktracefloor..
    6: withCallingHandlers
    5: domain$wrapSync
    4: promises::with_promise_domain
    3: captureStackTraces
    2: ..stacktraceoff..
    1: shiny::runApp
Avis : Error in strsplit: l'argument n'est pas une chaîne de caractères

Could edit your previous post by placing ``` before and after the output?

1 Like

unfortunately the stack trace is difficult to read and didnt give us linenumbers like it often would.
However

60: Context$new(getDefaultReactiveDomain(), "[download]")$run

looks suspicious to me, that it might be code related to one of the many download handlers, though this is a guess. I would potentially just comment out all the download buttons placed in the UI, and see if the error goes away with those. If so add them back one at a time until the error reproduces.

I suggest that you use version control on any substantially large piece of work, if you regularly make commits of your application from one working state to the next, it becomes easier to understand what new code you added relates to what new bugs introduced. something to think about.