As always when I submit code, I borked it. Here's the actual version, this time checked for correct behaviour.

let nsplit str sep =
  let try_split s =
    try Some (String.split s sep)
    with Invalid_string -> None
  let rec loop str result =
    match try_split str with
      | Some (a, b) -> loop b (a :: result)
      | None -> if result = [] then [str] else List.rev (str :: result)
  in loop str []

Sorry about the previous version. I should learn to be more careful.