diff --git a/CHANGELOG.md b/CHANGELOG.md index fbaac5c7..dbaf239a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unpublished Version / DEV] +### Credits + +- [Adam Talbot](https://github.com/adamrtalbot) + +### Software dependencies + ### Enhancements & fixes +- [[#387](https://github.com/nf-core/viralrecon/pull/387/files)] - Software closes gracefully when encountering an error + ## [[2.6.0](https://github.com/nf-core/viralrecon/releases/tag/2.6.0)] - 2023-03-23 ### Credits +### Software dependencies + Special thanks to the following for their code contributions to the release: - [Friederike Hanssen](https://github.com/FriederikeHanssen) diff --git a/lib/WorkflowCommons.groovy b/lib/WorkflowCommons.groovy index a1ec9776..dd805236 100755 --- a/lib/WorkflowCommons.groovy +++ b/lib/WorkflowCommons.groovy @@ -1,6 +1,7 @@ // // This file holds several functions common to the multiple workflows in the nf-core/viralrecon pipeline // +import nextflow.Nextflow class WorkflowCommons { @@ -9,12 +10,11 @@ class WorkflowCommons { // private static void genomeExistsError(params, log) { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + Nextflow.error("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + " Currently, the available genome keys are:\n" + " ${params.genomes.keySet().join(", ")}\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - System.exit(1) + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") } } @@ -121,14 +121,13 @@ class WorkflowCommons { def intersect = bed_contigs.intersect(fai_contigs) if (intersect.size() != bed_contigs.size()) { def diff = bed_contigs.minus(intersect).sort() - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + Nextflow.error("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Contigs in primer BED file do not match those in the reference genome:\n\n" + " ${diff.join('\n ')}\n\n" + " Please check:\n" + " - Primer BED file supplied with --primer_bed\n" + " - Genome FASTA file supplied with --fasta\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - System.exit(1) + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") } } diff --git a/lib/WorkflowIllumina.groovy b/lib/WorkflowIllumina.groovy index f151b2e1..68a0ee58 100755 --- a/lib/WorkflowIllumina.groovy +++ b/lib/WorkflowIllumina.groovy @@ -1,7 +1,7 @@ // // This file holds several functions specific to the workflow/illumina.nf in the nf-core/viralrecon pipeline // - +import nextflow.Nextflow import groovy.json.JsonSlurper class WorkflowIllumina { @@ -14,53 +14,45 @@ class WorkflowIllumina { // Generic parameter validation if (!valid_params['protocols'].contains(params.protocol)) { - log.error "Invalid option: '${params.protocol}'. Valid options for '--protocol': ${valid_params['protocols'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.protocol}'. Valid options for '--protocol': ${valid_params['protocols'].join(', ')}.") } if (!params.fasta) { - log.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." - System.exit(1) + Nextflow.error("Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file.") } if (!params.skip_kraken2 && !params.kraken2_db) { if (!params.kraken2_db_name) { - log.error "Please specify a valid name to build Kraken2 database for host e.g. '--kraken2_db_name human'." - System.exit(1) + Nextflow.error("Please specify a valid name to build Kraken2 database for host e.g. '--kraken2_db_name human'.") } } // Variant calling parameter validation if (params.variant_caller) { if (!valid_params['variant_callers'].contains(params.variant_caller)) { - log.error "Invalid option: ${params.variant_caller}. Valid options for '--variant_caller': ${valid_params['variant_callers'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.variant_caller}. Valid options for '--variant_caller': ${valid_params['variant_callers'].join(', ')}.") } } // Consensus calling parameter validation if (params.consensus_caller) { if (!valid_params['consensus_callers'].contains(params.consensus_caller)) { - log.error "Invalid option: ${params.consensus_caller}. Valid options for '--consensus_caller': ${valid_params['consensus_callers'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.consensus_caller}. Valid options for '--consensus_caller': ${valid_params['consensus_callers'].join(', ')}.") } } if (params.protocol == 'amplicon' && !params.skip_variants && !params.primer_bed) { - log.error "To perform variant calling in amplicon mode please provide a valid primer BED file e.g. '--primer_bed primers.bed'." - System.exit(1) + Nextflow.error("To perform variant calling in amplicon mode please provide a valid primer BED file e.g. '--primer_bed primers.bed'.") } // Assembly parameter validation def assemblers = params.assemblers ? params.assemblers.split(',').collect{ it.trim().toLowerCase() } : [] if ((valid_params['assemblers'] + assemblers).unique().size() != valid_params['assemblers'].size()) { - log.error "Invalid option: ${params.assemblers}. Valid options for '--assemblers': ${valid_params['assemblers'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.assemblers}. Valid options for '--assemblers': ${valid_params['assemblers'].join(', ')}.") } if (!valid_params['spades_modes'].contains(params.spades_mode)) { - log.error "Invalid option: ${params.spades_mode}. Valid options for '--spades_modes': ${valid_params['spades_modes'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.spades_mode}. Valid options for '--spades_modes': ${valid_params['spades_modes'].join(', ')}.") } } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 64147d3d..6fce10dd 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -1,6 +1,7 @@ // // This file holds several functions specific to the main.nf workflow in the nf-core/viralrecon pipeline // +import nextflow.Nextflow class WorkflowMain { @@ -84,18 +85,15 @@ class WorkflowMain { // Check sequencing platform def platformList = ['illumina', 'nanopore'] if (!params.platform) { - log.error "Platform not specified with e.g. '--platform illumina'. Valid options: ${platformList.join(', ')}." - System.exit(1) + Nextflow.error("Platform not specified with e.g. '--platform illumina'. Valid options: ${platformList.join(', ')}.") } else if (!platformList.contains(params.platform)) { - log.error "Invalid platform option: '${params.platform}'. Valid options: ${platformList.join(', ')}." - System.exit(1) + Nextflow.error("Invalid platform option: '${params.platform}'. Valid options: ${platformList.join(', ')}.") } // Check Nextclade dataset parameters if (!params.skip_consensus && !params.skip_nextclade) { if (!params.nextclade_dataset && !params.nextclade_dataset_name) { - log.error "Nextclade dataset not specified with '--nextclade_dataset' or '--nextclade_dataset_name'. A list of available datasets can be obtained using the Nextclade 'nextclade dataset list' command." - System.exit(1) + Nextflow.error("Nextclade dataset not specified with '--nextclade_dataset' or '--nextclade_dataset_name'. A list of available datasets can be obtained using the Nextclade 'nextclade dataset list' command.") } } } @@ -120,33 +118,30 @@ class WorkflowMain { if (genome_map.containsKey(primer_set_version)) { genome_map = genome_map[ primer_set_version ] } else { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + Nextflow.error("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " --primer_set_version '${primer_set_version}' not found!\n\n" + " Currently, the available primer set version keys are: ${genome_map.keySet().join(", ")}\n\n" + " Please check:\n" + " - The value provided to --primer_set_version (currently '${primer_set_version}')\n" + " - The value provided to --primer_set (currently '${primer_set}')\n" + " - The value provided to --genome (currently '${params.genome}')\n" + - " - Any custom config files provided to the pipeline.\n\n" + support_link - System.exit(1) + " - Any custom config files provided to the pipeline.\n\n" + support_link) } } else { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + Nextflow.error("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " --primer_set '${primer_set}' not found!\n\n" + " Currently, the available primer set keys are: ${genome_map.keySet().join(", ")}\n\n" + " Please check:\n" + " - The value provided to --primer_set (currently '${primer_set}')\n" + " - The value provided to --genome (currently '${params.genome}')\n" + - " - Any custom config files provided to the pipeline.\n\n" + support_link - System.exit(1) + " - Any custom config files provided to the pipeline.\n\n" + support_link) } } else { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + Nextflow.error("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' does not contain any primer sets!\n\n" + " Please check:\n" + " - The value provided to --genome (currently '${params.genome}')\n" + - " - Any custom config files provided to the pipeline.\n\n" + support_link - System.exit(1) + " - Any custom config files provided to the pipeline.\n\n" + support_link) } } if (genome_map.containsKey(attribute)) { diff --git a/lib/WorkflowNanopore.groovy b/lib/WorkflowNanopore.groovy index 8b2eb74a..e9983ee3 100755 --- a/lib/WorkflowNanopore.groovy +++ b/lib/WorkflowNanopore.groovy @@ -1,6 +1,7 @@ // // This file holds several functions specific to the workflow/nanopore.nf in the nf-core/viralrecon pipeline // +import nextflow.Nextflow class WorkflowNanopore { @@ -12,50 +13,41 @@ class WorkflowNanopore { // Generic parameter validation if (!params.fasta) { - log.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." - System.exit(1) + Nextflow.error("Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file.") } if (!params.primer_bed) { - log.error "Primer BED file not specified with e.g. '--primer_bed primers.bed' or via a detectable config file." - System.exit(1) + Nextflow.error("Primer BED file not specified with e.g. '--primer_bed primers.bed' or via a detectable config file.") } if (!params.artic_scheme) { - log.error "ARTIC scheme not specified with e.g. --artic_scheme 'nCoV-2019' or via a detectable config file." - System.exit(1) + Nextflow.error("ARTIC scheme not specified with e.g. --artic_scheme 'nCoV-2019' or via a detectable config file.") } if (!valid_params['artic_minion_caller'].contains(params.artic_minion_caller)) { - log.error "Invalid option: ${params.artic_minion_caller}. Valid options for '--artic_minion_caller': ${valid_params['artic_minion_caller'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.artic_minion_caller}. Valid options for '--artic_minion_caller': ${valid_params['artic_minion_caller'].join(', ')}.") } if (!valid_params['artic_minion_aligner'].contains(params.artic_minion_aligner)) { - log.error "Invalid option: ${params.artic_minion_aligner}. Valid options for '--artic_minion_aligner': ${valid_params['artic_minion_aligner'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: ${params.artic_minion_aligner}. Valid options for '--artic_minion_aligner': ${valid_params['artic_minion_aligner'].join(', ')}.") } if (!params.fastq_dir) { - log.error "Please specify a valid folder containing ONT basecalled fastq files generated by guppy_barcoder or guppy_basecaller e.g. '--fastq_dir ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/fastq_pass/" - System.exit(1) + Nextflow.error("Please specify a valid folder containing ONT basecalled fastq files generated by guppy_barcoder or guppy_basecaller e.g. '--fastq_dir ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/fastq_pass/") } if (params.artic_minion_caller == 'nanopolish') { if (!params.fast5_dir) { - log.error "Please specify a valid folder containing ONT fast5 files e.g. '--fast5_dir ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/fast5_pass/" - System.exit(1) + Nextflow.error("Please specify a valid folder containing ONT fast5 files e.g. '--fast5_dir ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/fast5_pass/") } if (!params.sequencing_summary) { - log.error "Please specify a valid ONT sequencing summary file e.g. '--sequencing_summary ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/sequencing_summary.txt" - System.exit(1) + Nextflow.error("Please specify a valid ONT sequencing summary file e.g. '--sequencing_summary ./20191023_1522_MC-110615_0_FAO93606_12bf9b4f/sequencing_summary.txt") } } if (params.artic_minion_caller == 'medaka') { if (!params.artic_minion_medaka_model) { - log.error "Please specify the '--artic_minion_medaka_model' parameter too if using the '--artic_minion_caller medaka' workflow.\nSee https://github.com/nanoporetech/medaka" - System.exit(1) + Nextflow.error("Please specify the '--artic_minion_medaka_model' parameter too if using the '--artic_minion_caller medaka' workflow.\nSee https://github.com/nanoporetech/medaka") } } }