Skip to content

Commit 612a9db

Browse files
Change to report errors from all exceptions and not just runtime errors
1 parent 380e97c commit 612a9db

File tree

1 file changed

+87
-94
lines changed

1 file changed

+87
-94
lines changed

src/falco.cpp

Lines changed: 87 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,6 @@
2727
#include "StreamReader.hpp"
2828
#include "smithlab_utils.hpp"
2929

30-
using std::cerr;
31-
using std::cout;
32-
using std::endl;
33-
using std::ifstream;
34-
using std::ofstream;
35-
using std::ostream;
36-
using std::runtime_error;
37-
using std::string;
38-
using std::to_string;
39-
using std::vector;
40-
41-
namespace fs = std::filesystem;
42-
4330
using std::chrono::duration_cast;
4431
using std::chrono::system_clock;
4532
using time_point = std::chrono::time_point<std::chrono::system_clock>;
@@ -54,17 +41,17 @@ get_seconds_since(const time_point &start_time) {
5441

5542
// Function to print progress nicely
5643
static inline void
57-
log_process(const string &s) {
44+
log_process(const std::string &s) {
5845
auto tmp = system_clock::to_time_t(system_clock::now());
59-
string time_fmt(std::ctime(&tmp));
46+
std::string time_fmt(std::ctime(&tmp));
6047
time_fmt.pop_back();
61-
cerr << "[" << time_fmt << "] " << s << endl;
48+
std::cerr << "[" << time_fmt << "] " << s << '\n';
6249
}
6350

6451
// Function to check existance of directory
6552
static bool
66-
dir_exists(const string &path) {
67-
return fs::exists(path) && fs::is_directory(path);
53+
dir_exists(const std::string &path) {
54+
return std::filesystem::exists(path) && std::filesystem::is_directory(path);
6855
}
6956

7057
// Read any file type until the end and logs progress
@@ -80,10 +67,10 @@ read_stream_into_stats(T &in, FastqStats &stats, FalcoConfig &falco_config) {
8067
const bool quiet = falco_config.quiet;
8168
ProgressBar progress(file_size, "running falco");
8269
if (!quiet)
83-
progress.report(cerr, 0);
70+
progress.report(std::cerr, 0);
8471
while (in.read_entry(stats, tot_bytes_read)) {
8572
if (!quiet && progress.time_to_report(tot_bytes_read))
86-
progress.report(cerr, tot_bytes_read);
73+
progress.report(std::cerr, tot_bytes_read);
8774
}
8875

8976
// if I could not get tile information from read names, I need to tell this to
@@ -92,16 +79,16 @@ read_stream_into_stats(T &in, FastqStats &stats, FalcoConfig &falco_config) {
9279
falco_config.do_tile = false;
9380

9481
if (!quiet && tot_bytes_read < file_size)
95-
progress.report(cerr, file_size);
82+
progress.report(std::cerr, file_size);
9683
}
9784

9885
// Write module content into html maker if requested
9986
template <typename T>
10087
void
10188
write_if_requested(T module, FastqStats &stats, const bool requested,
10289
const bool skip_text, const bool skip_html,
103-
const bool skip_short_summary, const string &filename,
104-
ostream &summary_txt, ostream &qc_data_txt,
90+
const bool skip_short_summary, const std::string &filename,
91+
std::ostream &summary_txt, std::ostream &qc_data_txt,
10592
HtmlMaker &html_maker) {
10693
html_maker.put_comment(module.placeholder_cs, module.placeholder_ce,
10794
requested);
@@ -137,36 +124,38 @@ void
137124
write_results(const FalcoConfig &falco_config, FastqStats &stats,
138125
const bool skip_text, const bool skip_html,
139126
const bool skip_short_summary, const bool do_call,
140-
const string &file_prefix, const string &outdir,
141-
const string &summary_filename, const string &data_filename,
142-
const string &report_filename) {
127+
const std::string &file_prefix, const std::string &outdir,
128+
const std::string &summary_filename,
129+
const std::string &data_filename,
130+
const std::string &report_filename) {
143131

144132
// Here we open the short summary ofstream
145-
ofstream summary_txt;
133+
std::ofstream summary_txt;
146134
if (!skip_short_summary) {
147-
const string summary_file =
148-
(summary_filename.empty() ? (outdir + "/" + file_prefix + "summary.txt")
149-
: (summary_filename));
150-
summary_txt.open(summary_file.c_str(), std::ofstream::binary);
135+
const std::string summary_file =
136+
summary_filename.empty() ? outdir + "/" + file_prefix + "summary.txt"
137+
: summary_filename;
138+
summary_txt.open(summary_file, std::ofstream::binary);
151139

152140
if (!summary_txt.good())
153-
throw runtime_error("Failed to create output summary file: " +
154-
summary_file);
141+
throw std::runtime_error("Failed to create output summary file: " +
142+
summary_file);
155143

156144
if (!falco_config.quiet)
157145
log_process("Writing summary to " + summary_file);
158146
}
159147

160148
// Here we open the full text summary
161-
ofstream qc_data_txt;
149+
std::ofstream qc_data_txt;
162150
if (!skip_text) {
163-
const string qc_data_file =
151+
const std::string qc_data_file =
164152
(data_filename.empty() ? (outdir + "/" + file_prefix + "fastqc_data.txt")
165153
: (data_filename));
166-
qc_data_txt.open(qc_data_file.c_str(), std::ofstream::binary);
154+
qc_data_txt.open(qc_data_file, std::ofstream::binary);
167155

168156
if (!qc_data_txt.good())
169-
throw runtime_error("Failed to create output data file: " + qc_data_file);
157+
throw std::runtime_error("Failed to create output data file: " +
158+
qc_data_file);
170159

171160
if (!falco_config.quiet)
172161
log_process("Writing text report to " + qc_data_file);
@@ -179,21 +168,21 @@ write_results(const FalcoConfig &falco_config, FastqStats &stats,
179168

180169
// Here we open the html ostream and maker object
181170
HtmlMaker html_maker = HtmlMaker();
182-
ofstream html;
171+
std::ofstream html;
183172
if (!skip_html) {
184173
// Decide html filename based on input
185-
const string html_file =
174+
const std::string html_file =
186175
(report_filename.empty()
187176
? (outdir + "/" + file_prefix + "fastqc_report.html")
188177
: (report_filename));
189178

190179
if (!falco_config.quiet)
191180
log_process("Writing HTML report to " + html_file);
192181

193-
html.open(html_file.c_str(), std::ofstream::binary);
182+
html.open(html_file, std::ofstream::binary);
194183
if (!html.good())
195-
throw runtime_error("Failed to create output HTML report file: " +
196-
html_file);
184+
throw std::runtime_error("Failed to create output HTML report file: " +
185+
html_file);
197186

198187
html_maker.put_file_details(falco_config);
199188
}
@@ -272,16 +261,17 @@ write_results(const FalcoConfig &falco_config, FastqStats &stats,
272261
html << html_maker.html_boilerplate;
273262
}
274263

275-
inline bool
276-
file_exists(const string &file_name) {
277-
return (access(file_name.c_str(), F_OK) == 0);
264+
[[nodiscard]] inline bool
265+
file_exists(const std::string &file_name) {
266+
return access(file_name.data(), F_OK) == 0;
278267
}
279268

280269
int
281270
main(int argc, const char **argv) {
282271

283272
try {
284-
static const string FALCO_VERSION = "falco " + FalcoConfig::FalcoVersion;
273+
static const std::string FALCO_VERSION =
274+
"falco " + FalcoConfig::FalcoVersion;
285275
bool help = false;
286276
bool version = false;
287277

@@ -294,20 +284,20 @@ main(int argc, const char **argv) {
294284

295285
// a tmp boolean to keep compatibility with FastQC
296286
bool tmp_compatibility_only = false;
297-
string tmp_compatibility_only_str;
287+
std::string tmp_compatibility_only_str;
298288

299289
FalcoConfig falco_config(argc, argv);
300290

301291
// if defined, read file as the file format specified by the user
302-
string forced_file_format;
292+
std::string forced_file_format;
303293

304294
// output directory in which to put files
305-
string outdir;
295+
std::string outdir;
306296

307297
// custom output filenames (if provided)
308-
string data_filename = "";
309-
string report_filename = "";
310-
string summary_filename = "";
298+
std::string data_filename = "";
299+
std::string report_filename = "";
300+
std::string summary_filename = "";
311301

312302
/****************** COMMAND LINE OPTIONS ********************/
313303
OptionParser opt_parse(argv[0],
@@ -548,39 +538,39 @@ main(int argc, const char **argv) {
548538
"other parts of a workflow.",
549539
false, allow_empty_input);
550540

551-
vector<string> leftover_args;
541+
std::vector<std::string> leftover_args;
552542
opt_parse.parse(argc, argv, leftover_args);
553543
if (argc == 1 || opt_parse.help_requested()) {
554-
cerr << opt_parse.help_message() << endl
555-
<< opt_parse.about_message() << endl;
544+
std::cerr << opt_parse.help_message() << '\n'
545+
<< opt_parse.about_message() << '\n';
556546
return EXIT_SUCCESS;
557547
}
558548
if (version) {
559-
cout << FALCO_VERSION << "\n";
549+
std::cerr << FALCO_VERSION << "\n";
560550
return EXIT_SUCCESS;
561551
}
562552
if (opt_parse.about_requested()) {
563-
cerr << opt_parse.about_message() << endl;
553+
std::cerr << opt_parse.about_message() << '\n';
564554
return EXIT_SUCCESS;
565555
}
566556
if (opt_parse.option_missing()) {
567-
cerr << opt_parse.option_missing_message() << endl;
557+
std::cerr << opt_parse.option_missing_message() << '\n';
568558
return EXIT_SUCCESS;
569559
}
570560

571561
if (leftover_args.size() == 0) {
572-
cerr << opt_parse.help_message() << endl;
562+
std::cerr << opt_parse.help_message() << '\n';
573563
return EXIT_SUCCESS;
574564
}
575565

576566
if (leftover_args.size() > 1 &&
577567
(!summary_filename.empty() || !report_filename.empty() ||
578568
!data_filename.empty())) {
579-
cerr << "ERROR: summary, report or data filename provided, but"
580-
<< " you are running falco with " << leftover_args.size()
581-
<< " inputs. We cannot allow this because multiple inputs"
582-
<< " require multiple outputs, so they will be resolved by"
583-
<< " the input filenames instead" << endl;
569+
std::cerr << "ERROR: summary, report or data filename provided, but"
570+
<< " you are running falco with " << leftover_args.size()
571+
<< " inputs. We cannot allow this because multiple inputs"
572+
<< " require multiple outputs, so they will be resolved by"
573+
<< " the input filenames instead\n";
584574
return EXIT_FAILURE;
585575
}
586576

@@ -590,61 +580,63 @@ main(int argc, const char **argv) {
590580
std::error_code ec;
591581
const bool empty_file = std::filesystem::is_empty(fn, ec);
592582
if (ec) {
593-
cerr << "Error reading file: " << fn << " (" << ec.message() << ")"
594-
<< endl;
583+
std::cerr << "Error reading file: " << fn << " (" << ec.message()
584+
<< ")\n";
595585
return EXIT_FAILURE;
596586
}
597587
else if (empty_file) {
598-
cerr << "Input file is empty: " << fn << endl;
588+
std::cerr << "Input file is empty: " << fn << '\n';
599589
return EXIT_FAILURE;
600590
}
601591
}
602592
}
603593

604594
if (!outdir.empty()) {
605595
if (!summary_filename.empty())
606-
cerr << "[WARNING] specifying custom output directory but also "
607-
<< "custom summary filename. Output " << outdir
608-
<< " will be disregarded and summary file will be saved to "
609-
<< summary_filename << endl;
596+
std::cerr << "[WARNING] specifying custom output directory but also "
597+
<< "custom summary filename. Output " << outdir
598+
<< " will be disregarded and summary file will be saved to "
599+
<< summary_filename << '\n';
610600

611601
if (!data_filename.empty())
612-
cerr << "[WARNING] specifying custom output directory but also "
613-
<< "custom data filename. Output " << outdir
614-
<< " will be disregarded and data file will be saved to "
615-
<< data_filename << endl;
602+
std::cerr << "[WARNING] specifying custom output directory but also "
603+
<< "custom data filename. Output " << outdir
604+
<< " will be disregarded and data file will be saved to "
605+
<< data_filename << '\n';
616606

617607
if (!report_filename.empty())
618-
cerr << "[WARNING] specifying custom output directory but also "
619-
<< "custom HTML Report filename. Output " << outdir
620-
<< " will be disregarded and HTML report file will be saved to "
621-
<< report_filename << endl;
608+
std::cerr
609+
<< "[WARNING] specifying custom output directory but also "
610+
<< "custom HTML Report filename. Output " << outdir
611+
<< " will be disregarded and HTML report file will be saved to "
612+
<< report_filename << '\n';
622613

623614
if (!dir_exists(outdir)) {
624615
if (!falco_config.quiet)
625616
log_process("creating directory for output: " + outdir);
626617

627618
// makes directory with r and w permission
628619
if (mkdir(outdir.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
629-
cerr << "failed to create directory: " << outdir
630-
<< ". Make sure you have write permissions on it!" << endl;
620+
std::cerr << "failed to create directory: " << outdir
621+
<< ". Make sure you have write permissions on it!\n";
631622
return EXIT_FAILURE;
632623
}
633624
}
634625
}
635-
const vector<string> all_seq_filenames(leftover_args);
626+
const std::vector<std::string> all_seq_filenames(leftover_args);
636627

637628
// check if all filenames exist
638629
bool all_files_exist = true;
639630
for (size_t i = 0; i < all_seq_filenames.size(); ++i) {
640631
if (!file_exists(all_seq_filenames[i])) {
641-
cerr << "ERROR! File does not exist: " << all_seq_filenames[i] << endl;
632+
std::cerr << "ERROR! File does not exist: " << all_seq_filenames[i]
633+
<< '\n';
642634
all_files_exist = false;
643635
}
644636
}
645637

646638
if (!all_files_exist) {
647-
throw runtime_error(
639+
throw std::runtime_error(
648640
"not all input files exist. Check stderr for detailed list"
649641
" of files that were not found");
650642
}
@@ -701,8 +693,8 @@ main(int argc, const char **argv) {
701693
read_stream_into_stats(in, stats, falco_config);
702694
}
703695
else {
704-
throw runtime_error("Cannot recognize file format for file " +
705-
falco_config.filename);
696+
throw std::runtime_error("Cannot recognize file format for file " +
697+
falco_config.filename);
706698
}
707699

708700
if (!falco_config.quiet) {
@@ -712,13 +704,14 @@ main(int argc, const char **argv) {
712704
stats.summarize();
713705

714706
// if oudir is empty we will set it as the filename path
715-
string cur_outdir;
707+
std::string cur_outdir;
716708

717709
const size_t last_slash_idx = filename.rfind('/');
718-
string file_basename = falco_config.filename.substr(last_slash_idx + 1);
710+
std::string file_basename =
711+
falco_config.filename.substr(last_slash_idx + 1);
719712
if (outdir.empty()) {
720713
// if file was given with relative path in the current dir, we set a dot
721-
if (last_slash_idx == string::npos) {
714+
if (last_slash_idx == std::string::npos) {
722715
cur_outdir = ".";
723716
file_basename = filename;
724717
}
@@ -731,20 +724,20 @@ main(int argc, const char **argv) {
731724
}
732725

733726
// Write results
734-
const string file_prefix =
727+
const std::string file_prefix =
735728
(all_seq_filenames.size() == 1) ? ("") : (file_basename + "_");
736729
write_results(falco_config, stats, skip_text, skip_html,
737730
skip_short_summary, do_call, file_prefix, cur_outdir,
738731
summary_filename, data_filename, report_filename);
739732

740733
/************************** TIME SUMMARY *****************************/
741734
if (!falco_config.quiet)
742-
cerr << "Elapsed time for file " << filename << ": "
743-
<< get_seconds_since(file_start_time) << "s" << endl;
735+
std::cerr << "Elapsed time for file " << filename << ": "
736+
<< get_seconds_since(file_start_time) << "s\n";
744737
}
745738
}
746-
catch (const runtime_error &e) {
747-
cerr << e.what() << endl;
739+
catch (const std::exception &e) {
740+
std::cerr << e.what() << '\n';
748741
return EXIT_FAILURE;
749742
}
750743
return EXIT_SUCCESS;

0 commit comments

Comments
 (0)