Hi,
I have written a function which
- checks if the input is a raw-vector
- if the input is a file-descriptor, it converts the file-content to a
raw-vector
- if the input is a URL, it converts the content to a raw vector
- if the input is a character-string, it is converted to a raw vector.
The URL-test relys on package pingr (line 17 in 'input_to_raw.R').
'is_online() tests if there is an internet-connection.
Line 18 tests if the URL is a valid URL. This test relys on the code in
'Rex.R'. (I don't know why I have to explicitly include 'library("rex")'
in the code since I have added rex to the Imports in the DESCRIPTION)
After incorporating this code in my package, the package passes all
tests both under Linux as on Windows(10).
devtools::check_win_devel however returns with this error:
Error in curl::curl_fetch_memory(url, handle = h) :
response reading failed
How can I solve this problem?
Ben
#' @title input_to_raw
#'
#' @return 'Raw' vector
#'
#' @param input Character vector length 1
#'
#' @description Convert \emph{input} to a length-1 character vector.
#'
#' @details If \emph{input} is a reference to a file, the number of bytes
#' corresponding to the size is read. If it is an URL, the URL is
read and converted to a 'Raw' vector.
#' The function does not catch errors.
#'
#' @export
input_to_raw <- function(input) {
type <- typeof(input)
pi <- pingr::is_online()
va <- grepl(re, input)
switch (type,
"raw" = raw_input <- input, # Raw
"character" = {
if (input == "") { # Empty input
raw_input <- raw(0)
} else if (file.exists(input)) { # File on filesystem
finfo <- file.info(input)
toread <- file(input, "rb")
raw_input <- readBin(toread, what = "raw", size = 1, n =
finfo$size)
close(toread)
} else if (pi && va && (get_URL <- httr::GET(input))$status
==200) {
raw_input <- get_URL$content
}
else { # String
raw_input <- charToRaw(input)
}
},
default = stop("Unknown input-type, please report the type of
the input."
)
)
return(raw_input)
}
--------------
library("rex")
valid_chars <- rex::rex(except_some_of(".", "/", " ", "-"))
re <- rex::rex(
start,
# protocol identifier (optional) + //
group(list("http", maybe("s")) %or% "ftp", "://"),
# user:pass authentication (optional)
maybe(non_spaces,
maybe(":", zero_or_more(non_space)),
"@"),
#host name
group(zero_or_more(valid_chars, zero_or_more("-")),
one_or_more(valid_chars)),
#domain name
zero_or_more(".", zero_or_more(valid_chars, zero_or_more("-")),
one_or_more(valid_chars)),
#TLD identifier
group(".", valid_chars %>% at_least(2)),
# server port number (optional)
maybe(":", digit %>% between(2, 5)),
# resource path (optional)
maybe("/", non_space %>% zero_or_more()),
end
)
[R-pkg-devel] Checking package in Windows fails
4 messages · Ben Engbers, Ivan Krylov
1 day later
On Mon, 15 Nov 2021 17:15:14 +0100
Ben Engbers <Ben.Engbers at Be-Logical.nl> wrote:
I don't know why I have to explicitly include 'library("rex")' in
the code since I have added rex to the Imports in the DESCRIPTION
Have you added the corresponding importFrom(...) [1] commands to your NAMESPACE file?
pi <- pingr::is_online() va <- grepl(re, input)
if (pi && va && (get_URL <-httr::GET(input))$status ==200)
Theoretically, this invites a class of errors known as "time-of-check to time-of-use" [2]: the user may go offline after the pingr::is_online() check but before the httr::GET() request uses the remote resource. But that's not what's causing you problems. The problem here is that pingr's definition of "is online" differs from "is able to fetch the URL you're testing", and I'm afraid it's impossible to solve in the general sense. What you could do instead is use tryCatch() to handle the error originating from curl and return something else instead. Or maybe letting the error propagate is the right idea. It may be bad for reproducibility when a function silently returns something completely different after the user goes offline. Then you would have to handle the error in your tests instead of the function. A simple option is wrapping the whole block of test code in try(), but that would handle all errors, including real bugs. A more complicated solution would be to handle the connection errors specifically, construct error objects of class "connection_error", signal them from the function and only handle those when testing via tryCatch(..., connection_error = ...). This would let you both (1) correctly propagate connection errors to the user instead of silently returning the URL itself and (2) not crash the tests despite that. See ?conditions for more information on that topic.
Thanks for your reply. I have moved new/edited 'input_to_raw' code and the validation code to another file with all kind of utility-functions and that seems to have solved that problem. (But I don't understand why that helped ;-() Hopefully then next version of my client will be using C++ to speed up reading from the socketConnection. And in that version I'll try to use tour suggestions. Since I am new to C++ that will take some time. Ben Op 16-11-2021 om 21:22 schreef Ivan Krylov:
On Mon, 15 Nov 2021 17:15:14 +0100 Ben Engbers <Ben.Engbers at Be-Logical.nl> wrote:
I don't know why I have to explicitly include 'library("rex")' in
the code since I have added rex to the Imports in the DESCRIPTION
Have you added the corresponding importFrom(...) [1] commands to your NAMESPACE file?
I don't edit the NAMESPACE file by hand. It is created by roxygen2.
On Wed, 17 Nov 2021 00:20:44 +0100
Ben Engbers <Ben.Engbers at Be-Logical.nl> wrote:
I don't edit the NAMESPACE file by hand. It is created by roxygen2.
Right. In that case, use an @importFrom tag: https://roxygen2.r-lib.org/articles/namespace.html#imports
Best regards, Ivan