@@ -27,6 +27,7 @@ use shadowsocks_service::{
2727use crate :: logging;
2828use crate :: {
2929 config:: { Config as ServiceConfig , RuntimeMode } ,
30+ error:: { ShadowsocksError , ShadowsocksResult } ,
3031 monitor, vparser,
3132} ;
3233
@@ -267,7 +268,7 @@ pub fn define_command_line_options(mut app: Command) -> Command {
267268}
268269
269270/// Create `Runtime` and `main` entry
270- pub fn create ( matches : & ArgMatches ) -> Result < ( Runtime , impl Future < Output = ExitCode > ) , ExitCode > {
271+ pub fn create ( matches : & ArgMatches ) -> ShadowsocksResult < ( Runtime , impl Future < Output = ShadowsocksResult > ) > {
271272 let ( config, runtime) = {
272273 let config_path_opt = matches. get_one :: < PathBuf > ( "CONFIG" ) . cloned ( ) . or_else ( || {
273274 if !matches. contains_id ( "SERVER_CONFIG" ) {
@@ -284,13 +285,8 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
284285 } ) ;
285286
286287 let mut service_config = match config_path_opt {
287- Some ( ref config_path) => match ServiceConfig :: load_from_file ( config_path) {
288- Ok ( c) => c,
289- Err ( err) => {
290- eprintln ! ( "loading config {config_path:?}, {err}" ) ;
291- return Err ( crate :: EXIT_CODE_LOAD_CONFIG_FAILURE . into ( ) ) ;
292- }
293- } ,
288+ Some ( ref config_path) => ServiceConfig :: load_from_file ( config_path)
289+ . map_err ( |err| ShadowsocksError :: LoadConfigFailure ( format ! ( "loading config {config_path:?}, {err}" ) ) ) ?,
294290 None => ServiceConfig :: default ( ) ,
295291 } ;
296292 service_config. set_options ( matches) ;
@@ -308,13 +304,8 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
308304 trace ! ( "{:?}" , service_config) ;
309305
310306 let mut config = match config_path_opt {
311- Some ( cpath) => match Config :: load_from_file ( & cpath, ConfigType :: Manager ) {
312- Ok ( cfg) => cfg,
313- Err ( err) => {
314- eprintln ! ( "loading config {cpath:?}, {err}" ) ;
315- return Err ( crate :: EXIT_CODE_LOAD_CONFIG_FAILURE . into ( ) ) ;
316- }
317- } ,
307+ Some ( cpath) => Config :: load_from_file ( & cpath, ConfigType :: Manager )
308+ . map_err ( |err| ShadowsocksError :: LoadConfigFailure ( format ! ( "loading config {cpath:?}, {err}" ) ) ) ?,
318309 None => Config :: new ( ConfigType :: Manager ) ,
319310 } ;
320311
@@ -421,13 +412,8 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
421412 }
422413
423414 if let Some ( acl_file) = matches. get_one :: < String > ( "ACL" ) {
424- let acl = match AccessControl :: load_from_file ( acl_file) {
425- Ok ( acl) => acl,
426- Err ( err) => {
427- eprintln ! ( "loading ACL \" {acl_file}\" , {err}" ) ;
428- return Err ( crate :: EXIT_CODE_LOAD_ACL_FAILURE . into ( ) ) ;
429- }
430- } ;
415+ let acl = AccessControl :: load_from_file ( acl_file)
416+ . map_err ( |err| ShadowsocksError :: LoadAclFailure ( format ! ( "loading ACL \" {acl_file}\" , {err}" ) ) ) ?;
431417 config. acl = Some ( acl) ;
432418 }
433419
@@ -470,18 +456,16 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
470456
471457 // DONE reading options
472458
473- if config. manager . is_none ( ) {
474- eprintln ! (
459+ config. manager . as_ref ( ) . ok_or_else ( || {
460+ ShadowsocksError :: InsufficientParams ( format ! (
475461 "missing `manager_address`, consider specifying it by --manager-address command line option, \
476462 or \" manager_address\" and \" manager_port\" keys in configuration file"
477- ) ;
478- return Err ( crate :: EXIT_CODE_INSUFFICIENT_PARAMS . into ( ) ) ;
479- }
463+ ) )
464+ } ) ?;
480465
481- if let Err ( err) = config. check_integrity ( ) {
482- eprintln ! ( "config integrity check failed, {err}" ) ;
483- return Err ( crate :: EXIT_CODE_LOAD_CONFIG_FAILURE . into ( ) ) ;
484- }
466+ config
467+ . check_integrity ( )
468+ . map_err ( |err| ShadowsocksError :: LoadConfigFailure ( format ! ( "config integrity check failed, {err}" ) ) ) ?;
485469
486470 #[ cfg( unix) ]
487471 if matches. get_flag ( "DAEMONIZE" ) || matches. get_raw ( "DAEMONIZE_PID_PATH" ) . is_some ( ) {
@@ -491,10 +475,9 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
491475
492476 #[ cfg( unix) ]
493477 if let Some ( uname) = matches. get_one :: < String > ( "USER" ) {
494- if let Err ( err) = crate :: sys:: run_as_user ( uname) {
495- eprintln ! ( "failed to change as user, error: {err}" ) ;
496- return Err ( crate :: EXIT_CODE_INSUFFICIENT_PARAMS . into ( ) ) ;
497- }
478+ crate :: sys:: run_as_user ( uname) . map_err ( |err| {
479+ ShadowsocksError :: InsufficientParams ( format ! ( "failed to change as user, error: {err}" ) )
480+ } ) ?;
498481 }
499482
500483 info ! ( "shadowsocks manager {} build {}" , crate :: VERSION , crate :: BUILD_TIME ) ;
@@ -526,17 +509,13 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
526509
527510 match future:: select ( server, abort_signal) . await {
528511 // Server future resolved without an error. This should never happen.
529- Either :: Left ( ( Ok ( ..) , ..) ) => {
530- eprintln ! ( "server exited unexpectedly" ) ;
531- crate :: EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY . into ( )
532- }
512+ Either :: Left ( ( Ok ( ..) , ..) ) => Err ( ShadowsocksError :: ServerExitUnexpectedly (
513+ "server exited unexpectedly" . to_owned ( ) ,
514+ ) ) ,
533515 // Server future resolved with error, which are listener errors in most cases
534- Either :: Left ( ( Err ( err) , ..) ) => {
535- eprintln ! ( "server aborted with {err}" ) ;
536- crate :: EXIT_CODE_SERVER_ABORTED . into ( )
537- }
516+ Either :: Left ( ( Err ( err) , ..) ) => Err ( ShadowsocksError :: ServerAborted ( format ! ( "server aborted with {err}" ) ) ) ,
538517 // The abort signal future resolved. Means we should just exit.
539- Either :: Right ( _) => ExitCode :: SUCCESS ,
518+ Either :: Right ( _) => Ok ( ( ) ) ,
540519 }
541520 } ;
542521
@@ -546,9 +525,12 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = Exi
546525/// Program entrance `main`
547526#[ inline]
548527pub fn main ( matches : & ArgMatches ) -> ExitCode {
549- match create ( matches) {
550- Ok ( ( runtime, main_fut) ) => runtime. block_on ( main_fut) ,
551- Err ( code) => code,
528+ match create ( matches) . and_then ( |( runtime, main_fut) | runtime. block_on ( main_fut) ) {
529+ Ok ( ( ) ) => ExitCode :: SUCCESS ,
530+ Err ( err) => {
531+ eprintln ! ( "{err}" ) ;
532+ err. exit_code ( ) . into ( )
533+ }
552534 }
553535}
554536
0 commit comments