@@ -3,7 +3,7 @@ defmodule Sentry.Config do
33
44 basic_opts_schema = [
55 dsn: [
6- type: { :or , [ :string , nil ] } ,
6+ type: { :or , [ nil , { :custom , __MODULE__ , :__validate_string_dsn__ , [ ] } ] } ,
77 default: nil ,
88 type_doc: "`t:String.t/0` or `nil`" ,
99 doc: """
@@ -316,7 +316,6 @@ defmodule Sentry.Config do
316316 opts
317317 |> normalize_included_environments ( )
318318 |> normalize_environment ( )
319- |> assert_dsn_has_no_query_params! ( )
320319 |> handle_deprecated_before_send ( )
321320
322321 { :error , error } ->
@@ -365,7 +364,7 @@ defmodule Sentry.Config do
365364 """
366365 end
367366
368- @ spec dsn ( ) :: String . t ( ) | nil
367+ @ spec dsn ( ) :: nil | { String . t ( ) , String . t ( ) , String . t ( ) }
369368 def dsn , do: get ( :dsn )
370369
371370 # TODO: remove me on v11.0.0, :included_environments has been deprecated
@@ -500,35 +499,6 @@ defmodule Sentry.Config do
500499 Keyword . update! ( config , :environment_name , & to_string / 1 )
501500 end
502501
503- defp assert_dsn_has_no_query_params! ( config ) do
504- if sentry_dsn = Keyword . get ( config , :dsn ) do
505- uri_dsn = URI . parse ( sentry_dsn )
506-
507- if uri_dsn . query do
508- raise ArgumentError , """
509- using a Sentry DSN with query parameters is not supported since v9.0.0 of this library.
510- The configured DSN was:
511-
512- #{ inspect ( sentry_dsn ) }
513-
514- The query string in that DSN is:
515-
516- #{ inspect ( uri_dsn . query ) }
517-
518- Please remove the query parameters from your DSN and pass them in as regular
519- configuration. Check out the guide to upgrade to 9.0.0 at:
520-
521- https://hexdocs.pm/sentry/upgrade-9.x.html
522-
523- See the documentation for the Sentry module for more information on configuration
524- in general.
525- """
526- end
527- end
528-
529- config
530- end
531-
532502 @ compile { :inline , fetch!: 1 }
533503 defp fetch! ( key ) do
534504 :persistent_term . get ( { :sentry_config , key } )
@@ -583,4 +553,69 @@ defmodule Sentry.Config do
583553 { :error , "expected #{ inspect ( key ) } to be a #{ inspect ( mod ) } struct, got: #{ inspect ( term ) } " }
584554 end
585555 end
556+
557+ def __validate_string_dsn__ ( dsn ) when is_binary ( dsn ) do
558+ uri = URI . parse ( dsn )
559+
560+ if uri . query do
561+ raise ArgumentError , """
562+ using a Sentry DSN with query parameters is not supported since v9.0.0 of this library.
563+ The configured DSN was:
564+
565+ #{ inspect ( dsn ) }
566+
567+ The query string in that DSN is:
568+
569+ #{ inspect ( uri . query ) }
570+
571+ Please remove the query parameters from your DSN and pass them in as regular
572+ configuration. Check out the guide to upgrade to 9.0.0 at:
573+
574+ https://hexdocs.pm/sentry/upgrade-9.x.html
575+
576+ See the documentation for the Sentry module for more information on configuration
577+ in general.
578+ """
579+ end
580+
581+ unless is_binary ( uri . path ) do
582+ throw ( "missing project ID at the end of the DSN URI: #{ inspect ( dsn ) } " )
583+ end
584+
585+ unless is_binary ( uri . userinfo ) do
586+ throw ( "missing user info in the DSN URI: #{ inspect ( dsn ) } " )
587+ end
588+
589+ { public_key , secret_key } =
590+ case String . split ( uri . userinfo , ":" , parts: 2 ) do
591+ [ public , secret ] -> { public , secret }
592+ [ public ] -> { public , nil }
593+ end
594+
595+ with { :ok , { base_path , project_id } } <- pop_project_id ( uri . path ) do
596+ new_path = Enum . join ( [ base_path , "api" , project_id , "envelope" ] , "/" ) <> "/"
597+ endpoint_uri = URI . merge ( % URI { uri | userinfo: nil } , new_path )
598+
599+ { :ok , { URI . to_string ( endpoint_uri ) , public_key , secret_key } }
600+ end
601+ catch
602+ message -> { :error , message }
603+ end
604+
605+ def __validate_string_dsn__ ( other ) do
606+ { :error , "expected :dsn to be a string or nil, got: #{ inspect ( other ) } " }
607+ end
608+
609+ defp pop_project_id ( uri_path ) do
610+ path = String . split ( uri_path , "/" )
611+ { project_id , path } = List . pop_at ( path , - 1 )
612+
613+ case Integer . parse ( project_id ) do
614+ { _project_id , "" } ->
615+ { :ok , { Enum . join ( path , "/" ) , project_id } }
616+
617+ _other ->
618+ { :error , "expected the DSN path to end with an integer project ID, got: #{ inspect ( path ) } " }
619+ end
620+ end
586621end
0 commit comments