2016-12-15 2 views
0

Это моя первая попытка написать что-нибудь в Erlang, так что, может быть, вопрос глупо.Dets Erlang не создает файл с open_file

Я пишу довольно простой сервер HTTP с помощью ковбойской

db_name() -> "DB_test". 

timestamp() -> 
    calendar:datetime_to_gregorian_seconds(calendar:universal_time()). 

sha(Str) -> 
    <<X:256/big-unsigned-integer>> = crypto:hash(sha256, Str), 
    lists:flatten(io_lib:format("~64.16.0b", [X])). 

handle_post(Req0, State) -> 
    Link = binary_to_list(cowboy_req:header(<<"link">>, Req0)), 
    dets:open_file(db_name(), []), 
    dets:insert(db_name(), {hashed_url(Link), Link, timestamp()}), 

    Req = cowboy_req:reply(200, 
     #{<<"content-type">> => <<"text/plain">>}, 
     sha(Link), 
     Req0), 
    {ok, Req, State}. 

Идея заключается в том, что запрос POST HTTP содержит заголовок «ссылку» с некоторой ссылкой. Получив такой запрос, мой сервер должен сохранить хэш в таблице dets вместе со ссылкой и временной меткой. Проблема в том, что файл «DB_test» не создается. Зачем?

ответ

1

Основываясь на вашем примере кода, трудно точно сказать, почему, поскольку вы игнорируете возвращаемые значения из обоих dets: open_file/2 и dets: insert/2. Оба они возвращают разные значения для случаев успеха и отказа; но не бросайте исключения. Для получения более подробной информации обратитесь к официальной документации: http://erlang.org/doc/man/dets.html

Простейшее решение для этого - сбой в процессе обработки соединения ковбоя в случаях неуспеха. Вы можете сделать это, делая что-то вроде следующего:

{ok, Ref} = dets:open_file(db_name(), []), 
ok = dets:insert(Ref, {hashed_url(Link), Link, timestamp()}), 

Это будет врезаться с badmatch исключением в случаях сбоя, когда возвращаемое значение не может быть шаблон согласован с левой части оператора, впоследствии вызывая ковбой, чтобы вернуть HTTP 500 клиенту. Затем вы увидите подробную информацию о том, какая фактическая ошибка была в журнале stacktrace.

Второе решение - явно обработать случаи сбоя, вы можете использовать ключевое слово «case» для этого. Примером может быть что-то вроде:

case dets:open_file(db_name(), []) of 
    {ok, Ref} -> 
     do_success_things(); 
    {error, Reason}=E -> 
     io:format("Unable to open database file: ~p~n", [E]), 
     do_failure_things(); 
end 

Для дальнейшего чтения, я настоятельно рекомендую Синтаксис функций и ошибок и исключений главы Learn вам некоторые Erlang для большой пользы: http://learnyousomeerlang.com/

Смежные вопросы