Как заставить пробовать / поймать на работу в эрланге - PullRequest
8 голосов
/ 10 декабря 2010

Я довольно новичок в Erlang и пытаюсь заставить работать базовый оператор try / catch. Я использую webmachine для обработки некоторых запросов, и все, что я действительно хочу сделать, это проанализировать некоторые данные JSON и вернуть их. В случае, если данные JSON являются недопустимыми, я просто хочу вернуть сообщение об ошибке. Вот код, который у меня есть пока что.

(данные JSON недействительны)

to_text(ReqData, Context) ->    
    Body =  "{\"firstName\": \"John\"\"lastName\": \"Smith\"}",
    try decode(Body) of
  _ -> {"Success! Json decoded!",ReqData,Context}
 catch
  _ -> {"Error! Json is invalid",ReqData,Context}
 end.         


decode(Body) ->
  {struct, MJ} = mochijson:decode(Body).

Код компилируется, но когда я запускаю его и отправляю запрос на текст, я получаю следующую ошибку.

error,{error,{case_clause,{{const,"lastName"},
                            ": \"Smith\"}",
                            {decoder,utf8,null,1,31,comma}}},
              [{mochijson,decode_object,3},
               {mochijson,json_decode,2},
               {webmachine_demo_resource,test,1},
               {webmachine_demo_resource,to_text,2},
               {webmachine_demo_resource,to_html,2},
               {webmachine_resource,resource_call,3},
               {webmachine_resource,do,3},
               {webmachine_decision_core,resource_call,1}]}}

Что именно я делаю не так? В документации сказано, что оператор «catch» обрабатывает все ошибки, или мне нужно что-то сделать, чтобы перехватить конкретную ошибку, выдаваемую mochijson: decode. Пожалуйста, любые выводы или советы будут полезны. Спасибо.

1 Ответ

18 голосов
/ 10 декабря 2010

Предложение catch «_ -> ...» перехватывает только исключения из класса throw. Чтобы отловить другие виды исключений, вам нужно написать шаблон в форме «Class: Term -> ...» (т.е. класс по умолчанию - «throw»). В вашем случае:

catch
  _:_ -> {"Error! Json is invalid",ReqData,Context}
end

Когда вы делаете это, вы всегда должны спрашивать себя почему вы ловите все возможные исключения. Если вы вызываете сторонний код и не знаете, как он может себя вести, это нормально. Если вы вызываете свой собственный код, помните, что вы в основном выбрасываете всю информацию о сбое, что может значительно усложнить отладку. Если вы можете сузить его до обнаружения только определенных ожидаемых случаев и позволить любым другим исключениям провалиться (чтобы вы увидели, где произошел настоящий сбой), сделайте это.

...