Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / templates / gleam@@main.erl
3.9 kB 118 lines
1-module('{{ application }}@@main'). 2-export([run/1, main/1]). 3 4-define(red, "\e[31;1m"). 5-define(grey, "\e[90m"). 6-define(reset_color, "\e[39m"). 7-define(reset_all, "\e[0m"). 8 9%%% Used by `gleam run` 10run(Module) -> 11 io:setopts(standard_io, [binary, {encoding, utf8}]), 12 io:setopts(standard_error, [{encoding, utf8}]), 13 process_flag(trap_exit, true), 14 Pid = spawn_link(fun() -> run_module(Module) end), 15 receive 16 {'EXIT', Pid, {Reason, [First|_] = StackTrace}} when is_tuple(First) -> 17 print_error_with_stacktrace(exit, Reason, StackTrace), 18 init:stop(1); 19 {'EXIT', Pid, Reason} when Reason =/= normal -> 20 print_error(exit, Reason), 21 init:stop(1) 22 end. 23 24%%% Used by escripts 25main(_) -> 26 run('{{ application }}'). 27 28run_module(Module) -> 29 try 30 {ok, _} = application:ensure_all_started('{{ application }}'), 31 erlang:process_flag(trap_exit, false), 32 Module:main(), 33 init:stop(0) 34 catch 35 Class:Reason:StackTrace -> 36 print_error_with_stacktrace(Class, Reason, StackTrace), 37 init:stop(1) 38 end. 39 40print_error_with_stacktrace(Class, Error, Stacktrace) -> 41 Printed = [ 42 ?red, "runtime error", ?reset_color, ": ", error_class(Class, Error), ?reset_all, 43 "\n\n", 44 error_message(Error), 45 "\n\n", 46 error_details(Class, Error), 47 "stacktrace:\n", 48 [error_frame(Line) || Line <- refine_first(Error, Stacktrace)] 49 ], 50 io:format(standard_error, "~ts~n", [Printed]). 51 52print_error(Class, Error) -> 53 Printed = [ 54 ?red, "runtime error", ?reset_color, ": ", error_class(Class, Error), ?reset_all, 55 "\n\n", 56 error_message(Error), 57 "\n\n", 58 "exit reason:\n ", print_term(Error), $\n 59 ], 60 io:format(standard_error, "~ts~n", [Printed]). 61 62refine_first(#{gleam_error := _, line := L}, [{M, F, A, [{file, Fi} | _]} | S]) -> 63 [{M, F, A, [{file, Fi}, {line, L}]} | S]; 64refine_first(_, S) -> 65 S. 66 67error_class(_, #{gleam_error := panic}) -> "panic"; 68error_class(_, #{gleam_error := todo}) -> "todo"; 69error_class(_, #{gleam_error := let_assert}) -> "let assert"; 70error_class(_, #{gleam_error := assert}) -> "assert"; 71error_class(Class, _) -> ["Erlang ", atom_to_binary(Class)]. 72 73error_message(#{gleam_error := _, message := M}) -> 74 M; 75error_message(undef) -> 76 <<"A function was called but it did not exist."/utf8 >>; 77error_message({case_clause, _}) -> 78 <<"No pattern matched in an Erlang case expression."/utf8>>; 79error_message({badmatch, _}) -> 80 <<"An Erlang assignment pattern did not match."/utf8>>; 81error_message(function_clause) -> 82 <<"No Erlang function clause matched the arguments it was called with."/utf8>>; 83error_message(_) -> 84 <<"An error occurred outside of Gleam."/utf8>>. 85 86error_details(_, #{gleam_error := let_assert, value := V}) -> 87 ["unmatched value:\n ", print_term(V), $\n, $\n]; 88error_details(_, {case_clause, V}) -> 89 ["unmatched value:\n ", print_term(V), $\n, $\n]; 90error_details(_, {badmatch, V}) -> 91 ["unmatched value:\n ", print_term(V), $\n, $\n]; 92error_details(_, #{gleam_error := _}) -> 93 []; 94error_details(error, function_clause) -> 95 []; 96error_details(error, undef) -> 97 []; 98error_details(C, E) -> 99 ["erlang:", atom_to_binary(C), $(, print_term(E), $), $\n, $\n]. 100 101print_term(T) -> 102 try 103 gleam@string:inspect(T) 104 catch 105 _:_ -> io_lib:format("~p", [T]) 106 end. 107 108error_frame({?MODULE, _, _, _}) -> []; 109error_frame({erl_eval, _, _, _}) -> []; 110error_frame({init, _, _, _}) -> []; 111error_frame({M, F, _, O}) -> 112 M1 = string:replace(atom_to_binary(M), "@", "/", all), 113 [" ", M1, $., atom_to_binary(F), error_frame_end(O), $\n]. 114 115error_frame_end([{file, Fi}, {line, L} | _]) -> 116 [?grey, $\s, Fi, $:, integer_to_binary(L), ?reset_all]; 117error_frame_end(_) -> 118 [?grey, " unknown source", ?reset_all].