smbache / ensurer

Ensure values are as expected at runtime
Other
84 stars 4 forks source link

Wish: Define global fail_with function #17

Closed bjoerm closed 1 year ago

bjoerm commented 7 years ago

Dear @smbache, Thanks a lot for this great package. I am frequently using it to ensure that data I read in from CSVs/data bases does not change unnoticed as well as that all my calculation stay in certain borders and no NAs suddenly occur after changes. As my alert system I use a fail_with function that forwards the error respective message to Slack (an instant messenger), which works great.

In practice every data source I read into R has its own functions (like get_customer_data(), get_sales_data(), ...). Each of these functions contains chained ensure_that statements that check for various cases. Following data operations are packed with ensurer checks as well.

Example:

# Error detection
  dim_country %>%
    ensurer::ensure_that(is.data.frame(.), fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(ncol(.) == 2, fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(nrow(.) > 1, fail_with = ensurer_fail_function) %>%
    # Prevent duplicates
    ensurer::ensure_that(length(.$country_code) == length(unique(.$country_code)), fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(length(.$country) == length(unique(.$country)), fail_with = ensurer_fail_function) %>%
    # No NAs in relevant columns
    ensurer::ensure_that(any(is.na(.$country_code)) == FALSE, fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(any(is.na(.$country)) == FALSE, fail_with = ensurer_fail_function) %>% 
    invisible(.)

As you can see, I have multiple cases I want to check. However, I have to provide each time that I want to call my individual fail_with function. This is tedious to code and one easily misses to enter an indivual fail_with function.

Wish/idea

I see the possibility to use ensures_that here, which in the example above would reduce the time I type in fail_with = ensurer_fail_function to one for that example. However, in my case, I have around 20 different places with ensurer checks in one single complex script. That means even with ensures_that, I would still end up with having to define this 20 times with the same fail_with option for the whole script. Thus, my wish for a global option to define a fail_with function.

I am perfectly fine, if you disagree with me on this and say that you deem ensures_that as the solution to my wish. ;-) Again, thanks a lot for providing this useful package!

smbache commented 7 years ago

I'm thinking what I'd prefer more:

ensurer::default_handler(some_handler)

baz <-
  foo %>%
  ensure_that(some_check(.))

or

new_ensure <- ensurer(fail_with = some_handler)

baz <-
  foo %>%
  new_ensure(some_check(.))

Probably, the second.

bjoerm commented 7 years ago

Thanks. Yes, the second has the advange of being more flexible.

bjoerm commented 1 year ago

I guess this issue is not needed anymore. ;-)