2016-12-15 58 views
0

這是我第一次嘗試在Erlang中寫任何東西,所以也許這個問題很愚蠢。Erlang的dets不會創建open_file文件

我用牛仔

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}. 

寫一個很簡單的HTTP服務器的想法是,一個HTTP POST請求包含一個「鏈接」了一些鏈接頭。接收到這樣的請求後,我的服務器應該將它的哈希存儲在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返回給客戶端。 然後你會看到詳細記錄堆棧跟蹤記錄中的實際錯誤

第二種解決方案是顯式處理失敗案例,您可以使用'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 

對於進一步的閱讀,我會強烈建議句法功能錯誤和異常瞭解你一些二郎偉大的良好的章:http://learnyousomeerlang.com/