Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# How to catch all exceptions

I know how to catch specific exceptions as in the following example:

let test_zip_archive candidate_zip_archive =
  let rc =
      try
        ZipFile.Open(candidate_zip_archive.ToString(), ZipArchiveMode.Read) |> ignore
      zip_file_ok
      with
      | :? System.IO.InvalidDataException -> not_a_zip_file
      | :? System.IO.FileNotFoundException -> file_not_found         
      | :? System.NotSupportedException -> unsupported_exception
  rc

I am reading a bunch of articles to see if I can use a generic exception in the with, like a wildcard match. Does such a construct exist, and, if so, what is it?

like image 461
octopusgrabbus Avatar asked May 18 '17 21:05

octopusgrabbus


2 Answers

Yes, you can do it like this:

let foo = 
  try
    //stuff (e.g.)
    //failwith "wat?"
    //raise (System.InvalidCastException())
    0 //return 0 when OK
  with ex ->
    printfn "%A" ex //ex is any exception 
    -1 //return -1 on error

This is the same as C#'s catch (Exception ex) { }

To discard the error you can do with _ -> -1 (which is the same as C#'s catch { })

like image 127
DaveShaw Avatar answered Oct 05 '22 00:10

DaveShaw


I like the way that you applied the type pattern test (see link). The pattern you are looking for is called the wildcard pattern. Probably you know that already, but didn't realise that you could use it here, too. The important thing to remember is that the with part of a try-catch block follows match semantics. So, all of the other nice pattern stuff applies here, too:

  • https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/pattern-matching

Using your code (and a few embellishments so that you can run it in FSI), here's how to do it:

#r "System.IO.Compression.FileSystem.dll"
#r "System.IO.Compression.dll"

open System  
open System.IO
open System.IO.Compression

type Status = 
  | Zip_file_ok
  | Not_a_zip_file
  | File_not_found
  | Unsupported_exception
  | I_am_a_catch_all

let test_zip_archive candidate_zip_archive =
  let rc() =
    try
      ZipFile.Open(candidate_zip_archive.ToString(), ZipArchiveMode.Read) |> ignore
      Zip_file_ok
    with
    | :? System.IO.InvalidDataException -> Not_a_zip_file
    | :? System.IO.FileNotFoundException -> File_not_found         
    | :? System.NotSupportedException -> Unsupported_exception
    | _ -> I_am_a_catch_all // otherwise known as "wildcard"
  rc
like image 35
sgtz Avatar answered Oct 04 '22 23:10

sgtz