Hi all! I’m fairly new to Elixir. I’ve read a book or two, but am just getting into using the language in practice. I recently needed to write a simple function to update a key in a JSON file. However, I found myself running into a lot of repetitive Go-esque error checking. I’m new to functional programming and I was wondering if there is a more idomatic way to handle this type of situation, or just a way to improve it. I’m not a fan of this style as it is because it’s a huge block of ever-indenting lines like old JavaScript. Here is a slimmed down example I came up with:
defmodule Test do
@doc """
Inserts the given JSON into the `data` field of `file`.
"""
def insert(file, data) do
# Read the contents of the file
case File.read(file) do
{:ok, content} ->
# Decode the file to JSON
case Poison.decode(content) do
{:ok, decoded_content} ->
# Encode the given data to JSON
case Poison.encode(data) do
{:ok, encoded_data} ->
# Prepare the updated data for insertion
final_data = Map.update(decoded_content, "data", encoded_data, fn _ -> encoded_data end)
# Encode the updated data
case Poison.encode(final_data) do
{:ok, encoded_final_data} ->
# Write the updated data to the file
case File.write(file, encoded_final_data) do
:ok -> IO.puts "Successfully updated file!"
{:error, reason} -> IO.puts "Could not write to file because #{reason}!"
end
{:error, {:invalid, reason}} -> IO.puts "Could not encode updated JSON because #{reason}!"
end
{:error, {:invalid, reason}} -> IO.puts "Could not encode given JSON because #{reason}!"
end
{:error, :invalid} -> IO.puts "Could not parse file to JSON!"
{:error, :invalid, reason} -> IO.puts "Could not parse file to JSON because #{reason}!"
end
{:error, reason} -> IO.puts "Could not read file because #{reason}!"
end
end
end
Keep in mind, I just wrote this as a quick example. It’s not my actual code nor is it perfect code. I’m just trying to demonstrate the error handling pattern I’m Talking about. Thanks in advance!